3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
26 gi
.require_version('RwDts', '1.0')
27 gi
.require_version('RwVnfrYang', '1.0')
28 from gi
.repository
import (
33 import rift
.openmano
.rift2openmano
as rift2openmano
34 import rift
.openmano
.openmano_client
as openmano_client
35 from . import rwnsmplugin
41 if sys
.version_info
< (3, 4, 4):
42 asyncio
.ensure_future
= asyncio
.async
45 DUMP_OPENMANO_DIR
= os
.path
.join(
46 os
.environ
["RIFT_ARTIFACTS"],
47 "openmano_descriptors"
51 def dump_openmano_descriptor(name
, descriptor_str
):
52 filename
= "{}_{}.yaml".format(
53 time
.strftime("%Y%m%d-%H%M%S"),
57 filepath
= os
.path
.join(
63 if not os
.path
.exists(DUMP_OPENMANO_DIR
):
64 os
.makedirs(DUMP_OPENMANO_DIR
)
66 with
open(filepath
, 'w') as hdl
:
67 hdl
.write(descriptor_str
)
70 print("Failed to dump openmano descriptor: %s" % str(e
))
74 class VnfrConsoleOperdataDtsHandler(object):
75 """ registers 'D,/vnfr:vnfr-console/vnfr:vnfr[id]/vdur[id]' and handles CRUD from DTS"""
77 def vnfr_vdu_console_xpath(self
):
78 """ path for resource-mgr"""
79 return ("D,/rw-vnfr:vnfr-console/rw-vnfr:vnfr[rw-vnfr:id='{}']/rw-vnfr:vdur[vnfr:id='{}']".format(self
._vnfr
_id
,self
._vdur
_id
))
81 def __init__(self
, dts
, log
, loop
, nsr
, vnfr_id
, vdur_id
, vdu_id
):
88 self
._vnfr
_id
= vnfr_id
89 self
._vdur
_id
= vdur_id
94 """ Register for VNFR VDU Operational Data read from dts """
97 def on_prepare(xact_info
, action
, ks_path
, msg
):
98 """ prepare callback from dts """
99 xpath
= ks_path
.to_xpath(RwVnfrYang
.get_schema())
101 "Got VNFR VDU Opdata xact_info: %s, action: %s): %s:%s",
102 xact_info
, action
, xpath
, msg
105 if action
== rwdts
.QueryAction
.READ
:
106 schema
= RwVnfrYang
.YangData_RwVnfr_VnfrConsole_Vnfr_Vdur
.schema()
107 path_entry
= schema
.keyspec_to_entry(ks_path
)
110 console_url
= yield from self
._loop
.run_in_executor(
112 self
._nsr
._http
_api
.get_instance_vm_console_url
,
117 self
._log
.debug("Got console response: %s for NSR ID %s vdur ID %s",
122 vdur_console
= RwVnfrYang
.YangData_RwVnfr_VnfrConsole_Vnfr_Vdur()
123 vdur_console
.id = self
._vdur
_id
125 vdur_console
.console_url
= console_url
127 vdur_console
.console_url
= 'none'
128 self
._log
.debug("Recevied console URL for vdu {} is {}".format(self
._vdu
_id
,vdur_console
))
129 except openmano_client
.InstanceStatusError
as e
:
130 self
._log
.error("Could not get NS instance console URL: %s",
132 vdur_console
= RwVnfrYang
.YangData_RwVnfr_VnfrConsole_Vnfr_Vdur()
133 vdur_console
.id = self
._vdur
_id
134 vdur_console
.console_url
= 'none'
136 xact_info
.respond_xpath(rsp_code
=rwdts
.XactRspCode
.ACK
,
137 xpath
=self
.vnfr_vdu_console_xpath
,
140 #raise VnfRecordError("Not supported operation %s" % action)
141 self
._log
.error("Not supported operation %s" % action
)
142 xact_info
.respond_xpath(rsp_code
=rwdts
.XactRspCode
.ACK
)
145 self
._log
.debug("Registering for VNFR VDU using xpath: %s",
146 self
.vnfr_vdu_console_xpath
)
147 hdl
= rift
.tasklets
.DTS
.RegistrationHandler(on_prepare
=on_prepare
,)
148 with self
._dts
.group_create() as group
:
149 self
._regh
= group
.register(xpath
=self
.vnfr_vdu_console_xpath
,
151 flags
=rwdts
.Flag
.PUBLISHER
,
156 class OpenmanoVnfr(object):
157 def __init__(self
, log
, loop
, cli_api
, vnfr
, nsd
):
160 self
._cli
_api
= cli_api
162 self
._vnfd
_id
= vnfr
.vnfd
.id
166 self
._created
= False
172 return rift2openmano
.RiftVNFD(self
._vnfr
.vnfd
)
179 def rift_vnfd_id(self
):
183 def openmano_vnfd_id(self
):
187 def openmano_vnfd(self
):
188 self
._log
.debug("Converting vnfd %s from rift to openmano", self
.vnfd
.id)
189 openmano_vnfd
= rift2openmano
.rift2openmano_vnfd(self
.vnfd
, self
.nsd
)
193 def openmano_vnfd_yaml(self
):
194 return yaml
.safe_dump(self
.openmano_vnfd
, default_flow_style
=False)
198 self
._log
.debug("Creating openmano vnfd")
199 openmano_vnfd
= self
.openmano_vnfd
200 name
= openmano_vnfd
["vnf"]["name"]
202 # If the name already exists, get the openmano vnfd id
203 name_uuid_map
= yield from self
._loop
.run_in_executor(
205 self
._cli
_api
.vnf_list
,
208 if name
in name_uuid_map
:
209 vnf_id
= name_uuid_map
[name
]
210 self
._log
.debug("Vnf already created. Got existing openmano vnfd id: %s", vnf_id
)
211 self
._vnf
_id
= vnf_id
214 self
._vnf
_id
, _
= yield from self
._loop
.run_in_executor(
216 self
._cli
_api
.vnf_create
,
217 self
.openmano_vnfd_yaml
,
220 fpath
= dump_openmano_descriptor(
221 "{}_vnf".format(name
),
222 self
.openmano_vnfd_yaml
225 self
._log
.debug("Dumped Openmano VNF descriptor to: %s", fpath
)
231 if not self
._created
:
234 self
._log
.debug("Deleting openmano vnfd")
235 if self
._vnf
_id
is None:
236 self
._log
.warning("Openmano vnf id not set. Cannot delete.")
239 yield from self
._loop
.run_in_executor(
241 self
._cli
_api
.vnf_delete
,
246 class OpenmanoNSRecordState(Enum
):
247 """ Network Service Record State """
248 # Make sure the values match with NetworkServiceRecordState
250 INSTANTIATION_PENDING
= 102
262 class OpenmanoNsr(object):
265 def __init__(self
, dts
, log
, loop
, publisher
, cli_api
, http_api
, nsd_msg
, nsr_config_msg
,key_pairs
, rift_vnfd_id
=None):
269 self
._publisher
= publisher
270 self
._cli
_api
= cli_api
271 self
._http
_api
= http_api
273 self
._nsd
_msg
= nsd_msg
274 self
._nsr
_config
_msg
= nsr_config_msg
279 self
._vdur
_console
_handler
= {}
280 self
._key
_pairs
= key_pairs
282 self
._nsd
_uuid
= None
283 self
._nsr
_uuid
= None
287 self
._created
= False
289 self
._monitor
_task
= None
290 self
._rift
_vnfd
_id
= rift_vnfd_id
291 self
._state
= OpenmanoNSRecordState
.INIT
295 return rift2openmano
.RiftNSD(self
._nsd
_msg
)
302 def nsr_config_msg(self
):
303 return self
._nsr
_config
_msg
311 return self
._key
_pairs
315 return {v
.rift_vnfd_id
: v
.vnfd
for v
in self
._vnfrs
}
319 return {v
.rift_vnfd_id
: v
.openmano_vnfd_id
for v
in self
._vnfrs
}
326 def openmano_nsd_yaml(self
):
327 self
._log
.debug("Converting nsd %s from rift to openmano", self
.nsd
.id)
328 openmano_nsd
= rift2openmano
.rift2openmano_nsd(self
.nsd
, self
.vnfds
,self
.vnfr_ids
)
329 return yaml
.safe_dump(openmano_nsd
, default_flow_style
=False)
332 def scaling_group_nsd_yaml(self
):
333 self
._log
.debug("Creating Scaling Group Scenarion Descriptor for VNF %s", self
._rift
_vnfd
_id
)
334 openmano_vnfd_nsd
= rift2openmano
.rift2openmano_vnfd_nsd(self
.nsd
, self
.vnfds
, self
.vnfr_ids
, self
._rift
_vnfd
_id
)
335 return yaml
.safe_dump(vnfd_nsd
, default_flow_style
=False)
338 def get_ssh_key_pairs(self
):
341 for authorized_key
in self
._nsr
_config
_msg
.ssh_authorized_key
:
342 self
._log
.debug("Key pair ref present is %s",authorized_key
.key_pair_ref
)
343 if authorized_key
.key_pair_ref
in self
._key
_pairs
:
344 key_pairs
.append(self
._key
_pairs
[authorized_key
.key_pair_ref
].key
)
346 for authorized_key
in self
._nsd
_msg
.key_pair
:
347 self
._log
.debug("Key pair NSD is %s",authorized_key
)
348 key_pairs
.append(authorized_key
.key
)
351 cloud_config
["key-pairs"] = key_pairs
354 for user_entry
in self
._nsr
_config
_msg
.user
:
355 self
._log
.debug("User present is %s",user_entry
)
357 user
["name"] = user_entry
.name
358 user
["key-pairs"] = list()
359 for ssh_key
in user_entry
.ssh_authorized_key
:
360 if ssh_key
.key_pair_ref
in self
._key
_pairs
:
361 user
["key-pairs"].append(self
._key
_pairs
[ssh_key
.key_pair_ref
].key
)
364 for user_entry
in self
._nsd
_msg
.user
:
365 self
._log
.debug("User present in NSD is %s",user_entry
)
367 user
["name"] = user_entry
.name
368 user
["key-pairs"] = list()
369 for ssh_key
in user_entry
.key_pair
:
370 user
["key-pairs"].append(ssh_key
.key
)
374 cloud_config
["users"] = users
376 self
._log
.debug("Cloud config formed is %s",cloud_config
)
381 def openmano_instance_create_yaml(self
):
382 self
._log
.debug("Creating instance-scenario-create input file for nsd %s with name %s", self
.nsd
.id, self
._nsr
_config
_msg
.name
, self
._rift
_vnfd
_id
)
383 openmano_instance_create
= {}
384 openmano_instance_create
["name"] = self
._nsr
_config
_msg
.name
385 openmano_instance_create
["description"] = self
._nsr
_config
_msg
.description
386 openmano_instance_create
["scenario"] = self
._nsd
_uuid
388 #cloud_config = self.get_ssh_key_pairs()
390 # openmano_instance_create["cloud-config"] = cloud_config
391 if self
._nsr
_config
_msg
.has_field("om_datacenter"):
392 openmano_instance_create
["datacenter"] = self
._nsr
_config
_msg
.om_datacenter
393 openmano_instance_create
["vnfs"] = {}
394 for vnfr
in self
._vnfrs
:
395 if "om_datacenter" in vnfr
.vnfr
.vnfr_msg
:
396 vnfr_name
= vnfr
.vnfr
.vnfd
.name
+ "__" + str(vnfr
.vnfr
.vnfr_msg
.member_vnf_index_ref
)
397 openmano_instance_create
["vnfs"][vnfr_name
] = {"datacenter": vnfr
.vnfr
.vnfr_msg
.om_datacenter
}
398 openmano_instance_create
["networks"] = {}
399 for vld_msg
in self
._nsd
_msg
.vld
:
400 openmano_instance_create
["networks"][vld_msg
.name
] = {}
401 openmano_instance_create
["networks"][vld_msg
.name
]["sites"] = list()
402 for vlr
in self
._vlrs
:
403 if vlr
.vld_msg
.name
== vld_msg
.name
:
404 self
._log
.debug("Received VLR name %s, VLR DC: %s for VLD: %s",vlr
.vld_msg
.name
,
405 vlr
.om_datacenter_name
,vld_msg
.name
)
406 #network["vim-network-name"] = vld_msg.name
409 if vld_msg
.vim_network_name
:
410 network
["netmap-use"] = vld_msg
.vim_network_name
411 elif vlr
._ip
_profile
and vlr
._ip
_profile
.has_field("ip_profile_params"):
412 ip_profile_params
= vlr
._ip
_profile
.ip_profile_params
413 if ip_profile_params
.ip_version
== "ipv6":
414 ip_profile
['ip-version'] = "IPv6"
416 ip_profile
['ip-version'] = "IPv4"
417 if ip_profile_params
.has_field('subnet_address'):
418 ip_profile
['subnet-address'] = ip_profile_params
.subnet_address
419 if ip_profile_params
.has_field('gateway_address'):
420 ip_profile
['gateway-address'] = ip_profile_params
.gateway_address
421 if ip_profile_params
.has_field('dns_server') and len(ip_profile_params
.dns_server
) > 0:
422 ip_profile
['dns-address'] = ip_profile_params
.dns_server
[0].address
423 if ip_profile_params
.has_field('dhcp_params'):
424 ip_profile
['dhcp'] = {}
425 ip_profile
['dhcp']['enabled'] = ip_profile_params
.dhcp_params
.enabled
426 ip_profile
['dhcp']['start-address'] = ip_profile_params
.dhcp_params
.start_address
427 ip_profile
['dhcp']['count'] = ip_profile_params
.dhcp_params
.count
429 network
["netmap-create"] = vlr
.name
430 if vlr
.om_datacenter_name
:
431 network
["datacenter"] = vlr
.om_datacenter_name
432 elif vld_msg
.has_field("om_datacenter"):
433 network
["datacenter"] = vld_msg
.om_datacenter
434 elif "datacenter" in openmano_instance_create
:
435 network
["datacenter"] = openmano_instance_create
["datacenter"]
437 openmano_instance_create
["networks"][vld_msg
.name
]["sites"].append(network
)
439 openmano_instance_create
["networks"][vld_msg
.name
]['ip-profile'] = ip_profile
441 return yaml
.safe_dump(openmano_instance_create
, default_flow_style
=False,width
=1000)
444 def scaling_instance_create_yaml(self
):
445 self
._log
.debug("Creating instance-scenario-create input file for nsd %s with name %s", self
.nsd
.id, self
._nsr
_config
_msg
.name
)
446 scaling_instance_create
= {}
447 scaling_instance_create
["vnfs"] = {}
448 scaling_instance_create
["name"] = self
._nsr
_config
_msg
.name
+"scal1"
449 scaling_instance_create
["description"] = "Scaling Group Instance Scenario File"
450 scaling_instance_create
["scenario"] = self
._rift
_vnfd
_id
452 if self
._nsr
_config
_msg
.has_field("om_datacenter"):
453 scaling_instance_create
["datacenter"] = self
._nsr
_config
_msg
.om_datacenter
454 scaling_instance_create
["vnfs"] = {}
455 for vnfr
in self
._vnfrs
:
456 if "om_datacenter" in vnfr
.vnfr
.vnfr_msg
:
457 vnfr_name
= vnfr
.vnfr
.vnfd
.name
+ "__" + str(vnfr
.vnfr
.vnfr_msg
.member_vnf_index_ref
)
458 scaling_instance_create
["vnfs"][vnfr_name
] = {"datacenter": vnfr
.vnfr
.vnfr_msg
.om_datacenter
}
459 scaling_instance_create
["networks"] = {}
460 for vld_msg
in self
._nsd
_msg
.vld
:
461 scaling_instance_create
["networks"][vld_msg
.name
] = {}
462 scaling_instance_create
["networks"][vld_msg
.name
]["sites"] = list()
463 for vlr
in self
._vlrs
:
464 if vlr
.vld_msg
.name
== vld_msg
.name
:
465 self
._log
.debug("Received VLR name %s, VLR DC: %s for VLD: %s",vlr
.vld_msg
.name
,
466 vlr
.om_datacenter_name
,vld_msg
.name
)
467 #network["vim-network-name"] = vld_msg.name
470 if vld_msg
.vim_network_name
:
471 network
["netmap-use"] = vld_msg
.vim_network_name
472 return yaml
.safe_dump(scaling_instance_create
, default_flow_style
=False,width
=1000)
476 def add_vlr(self
, vlr
):
477 self
._vlrs
.append(vlr
)
478 yield from self
._publisher
.publish_vlr(None, vlr
.vlr_msg
)
479 yield from asyncio
.sleep(1, loop
=self
._loop
)
482 def remove_vlr(self
, vlr
):
483 if vlr
in self
._vlrs
:
484 self
._vlrs
.remove(vlr
)
485 yield from self
._publisher
.unpublish_vlr(None, vlr
.vlr_msg
)
486 yield from asyncio
.sleep(1, loop
=self
._loop
)
489 def delete_vlr(self
, vlr
):
490 if vlr
in self
._vlrs
:
491 self
._vlrs
.remove(vlr
)
492 if not vlr
.vld_msg
.vim_network_name
:
493 yield from self
._loop
.run_in_executor(
495 self
._cli
_api
.ns_vim_network_delete
,
497 vlr
.om_datacenter_name
)
498 yield from self
._publisher
.unpublish_vlr(None, vlr
.vlr_msg
)
499 yield from asyncio
.sleep(1, loop
=self
._loop
)
502 def add_vnfr(self
, vnfr
):
503 vnfr
= OpenmanoVnfr(self
._log
, self
._loop
, self
._cli
_api
, vnfr
, nsd
=self
.nsd
)
504 yield from vnfr
.create()
505 self
._vnfrs
.append(vnfr
)
508 def add_nsr(self
, nsr
, vnfr
):
509 self
._nsrs
[vnfr
.id] = nsr
513 if not self
._created
:
514 self
._log
.debug("NSD wasn't created. Skipping delete.")
517 self
._log
.debug("Deleting openmano nsr")
519 yield from self
._loop
.run_in_executor(
521 self
._cli
_api
.ns_delete
,
525 self
._log
.debug("Deleting openmano vnfrs")
526 for vnfr
in self
._vnfrs
:
527 yield from vnfr
.delete()
532 self
._log
.debug("Creating openmano scenario")
533 name_uuid_map
= yield from self
._loop
.run_in_executor(
535 self
._cli
_api
.ns_list
,
538 if self
._nsd
_msg
.name
in name_uuid_map
:
539 self
._log
.debug("Found existing openmano scenario")
540 self
._nsd
_uuid
= name_uuid_map
[self
._nsd
_msg
.name
]
544 # Use the nsd uuid as the scenario name to rebind to existing
545 # scenario on reload or to support muliple instances of the name
547 self
._nsd
_uuid
, _
= yield from self
._loop
.run_in_executor(
549 self
._cli
_api
.ns_create
,
550 self
.openmano_nsd_yaml
,
553 fpath
= dump_openmano_descriptor(
554 "{}_nsd".format(self
._nsd
_msg
.name
),
555 self
.openmano_nsd_yaml
,
558 self
._log
.debug("Dumped Openmano NS descriptor to: %s", fpath
)
563 def scaling_scenario_create(self
):
564 self
._log
.debug("Creating Openmano Scenario for the Scaling Group VNF")
565 self
._vnfd
_nsd
_uuid
, _
= yield from self
._loop
.run_in_executor(
567 self
._cli
_api
.ns_create
,
568 self
.scaling_group_nsd_yaml
,
571 fpath
= dump_openmano_descriptor(
572 "{}_scaling_group_nsd".format(self
._rift
_vnfd
_id
),
573 self
.scaling_group_nsd_yaml
,
575 self
._log
.debug("Dumped Scaling group scenario to '%s'", fpath
)
579 def instance_monitor_task(self
):
580 self
._log
.debug("Starting Instance monitoring task")
582 start_time
= time
.time()
586 yield from asyncio
.sleep(1, loop
=self
._loop
)
589 instance_resp_json
= yield from self
._loop
.run_in_executor(
591 self
._http
_api
.get_instance
,
595 self
._log
.debug("Got instance response: %s for NSR ID %s",
599 except openmano_client
.InstanceStatusError
as e
:
600 self
._log
.error("Could not get NS instance status: %s", str(e
))
603 def all_vms_active(vnf
):
604 for vm
in vnf
["vms"]:
605 vm_status
= vm
["status"]
607 if vm_status
!= "ACTIVE":
608 self
._log
.debug("VM is not yet active: %s (status: %s)", vm_uuid
, vm_status
)
613 def any_vm_active_nomgmtip(vnf
):
614 for vm
in vnf
["vms"]:
615 vm_status
= vm
["status"]
617 if vm_status
!= "ACTIVE":
618 self
._log
.debug("VM is not yet active: %s (status: %s)", vm_uuid
, vm_status
)
623 def any_vms_error(vnf
):
624 for vm
in vnf
["vms"]:
625 vm_status
= vm
["status"]
626 vm_vim_info
= vm
["vim_info"]
628 if vm_status
== "ERROR":
629 self
._log
.error("VM Error: %s (vim_info: %s)", vm_uuid
, vm_vim_info
)
634 def get_vnf_ip_address(vnf
):
635 if "ip_address" in vnf
:
636 return vnf
["ip_address"].strip()
639 def get_vnf_mac_address(vnf
):
640 if "mac_address" in vnf
:
641 return vnf
["mac_address"].strip()
644 def get_ext_cp_info(vnf
):
646 for vm
in vnf
["vms"]:
647 if "interfaces" not in vm
:
650 for intf
in vm
["interfaces"]:
651 if "external_name" not in intf
:
654 if not intf
["external_name"]:
657 ip_address
= intf
["ip_address"]
658 if ip_address
is None:
659 ip_address
= "0.0.0.0"
661 mac_address
= intf
["mac_address"]
662 if mac_address
is None:
663 mac_address
="00:00:00:00:00:00"
665 cp_info_list
.append((intf
["external_name"], ip_address
, mac_address
))
669 def get_vnf_status(vnfr
):
670 # When we create an openmano descriptor we use <name>__<idx>
671 # to come up with openmano constituent VNF name. Use this
672 # knowledge to map the vnfr back.
673 openmano_vnfr_suffix
= "__{}".format(
674 vnfr
.vnfr
.vnfr_msg
.member_vnf_index_ref
677 for vnf
in instance_resp_json
["vnfs"]:
678 if vnf
["vnf_name"].endswith(openmano_vnfr_suffix
):
681 self
._log
.warning("Could not find vnf status with name that ends with: %s",
682 openmano_vnfr_suffix
)
685 for vnfr
in self
._vnfrs
:
686 if vnfr
in active_vnfs
:
687 # Skipping, so we don't re-publish the same VNF message.
690 vnfr_msg
= vnfr
.vnfr
.vnfr_msg
.deep_copy()
691 vnfr_msg
.operational_status
= "init"
694 vnf_status
= get_vnf_status(vnfr
)
695 self
._log
.debug("Found VNF status: %s", vnf_status
)
696 if vnf_status
is None:
697 self
._log
.error("Could not find VNF status from openmano")
698 self
._state
= OpenmanoNSRecordState
.FAILED
699 vnfr_msg
.operational_status
= "failed"
700 yield from self
._publisher
.publish_vnfr(None, vnfr_msg
)
703 # If there was a VNF that has a errored VM, then just fail the VNF and stop monitoring.
704 if any_vms_error(vnf_status
):
705 self
._log
.debug("VM was found to be in error state. Marking as failed.")
706 self
._state
= OpenmanoNSRecordState
.FAILED
707 vnfr_msg
.operational_status
= "failed"
708 yield from self
._publisher
.publish_vnfr(None, vnfr_msg
)
711 if (time
.time() - start_time
) > OpenmanoNsr
.TIMEOUT_SECS
:
712 self
._log
.error("NSR timed out before reaching running state")
713 self
._state
= OpenmanoNSRecordState
.FAILED
714 vnfr_msg
.operational_status
= "failed"
715 yield from self
._publisher
.publish_vnfr(None, vnfr_msg
)
718 if all_vms_active(vnf_status
):
719 vnf_ip_address
= get_vnf_ip_address(vnf_status
)
720 vnf_mac_address
= get_vnf_mac_address(vnf_status
)
722 if vnf_ip_address
is None:
723 self
._log
.warning("No IP address obtained "
724 "for VNF: {}, will retry.".format(
725 vnf_status
['vnf_name']))
728 self
._log
.debug("All VMs in VNF are active. Marking as running.")
729 vnfr_msg
.operational_status
= "running"
731 self
._log
.debug("Got VNF ip address: %s, mac-address: %s", vnf_ip_address
, vnf_mac_address
)
732 vnfr_msg
.mgmt_interface
.ip_address
= vnf_ip_address
733 vnfr_msg
.vnf_configuration
.config_access
.mgmt_ip_address
= vnf_ip_address
736 for vm
in vnf_status
["vms"]:
737 if vm
["uuid"] not in self
._vdur
_console
_handler
:
738 vdur_console_handler
= VnfrConsoleOperdataDtsHandler(self
._dts
, self
._log
, self
._loop
,
739 self
, vnfr_msg
.id,vm
["uuid"],vm
["name"])
740 yield from vdur_console_handler
.register()
741 self
._vdur
_console
_handler
[vm
["uuid"]] = vdur_console_handler
743 vdur_msg
= vnfr_msg
.vdur
.add()
744 vdur_msg
.vim_id
= vm
["vim_vm_id"]
745 vdur_msg
.id = vm
["uuid"]
747 # Add connection point information for the config manager
748 cp_info_list
= get_ext_cp_info(vnf_status
)
749 for (cp_name
, cp_ip
, cp_mac_addr
) in cp_info_list
:
750 cp
= vnfr_msg
.connection_point
.add()
752 cp
.short_name
= cp_name
753 cp
.ip_address
= cp_ip
754 cp
.mac_address
= cp_mac_addr
756 yield from self
._publisher
.publish_vnfr(None, vnfr_msg
)
757 active_vnfs
.append(vnfr
)
760 except Exception as e
:
761 vnfr_msg
.operational_status
= "failed"
762 self
._state
= OpenmanoNSRecordState
.FAILED
763 yield from self
._publisher
.publish_vnfr(None, vnfr_msg
)
764 self
._log
.exception("Caught exception publishing vnfr info: %s", str(e
))
767 if len(active_vnfs
) == len(self
._vnfrs
):
768 self
._state
= OpenmanoNSRecordState
.RUNNING
769 self
._log
.info("All VNF's are active. Exiting NSR monitoring task")
773 def deploy(self
,nsr_msg
):
774 if self
._nsd
_uuid
is None:
775 raise ValueError("Cannot deploy an uncreated nsd")
777 self
._log
.debug("Deploying openmano scenario")
779 name_uuid_map
= yield from self
._loop
.run_in_executor(
781 self
._cli
_api
.ns_instance_list
,
784 if self
._nsr
_config
_msg
.name
in name_uuid_map
:
785 self
._log
.debug("Found existing instance with nsr name: %s", self
._nsr
_config
_msg
.name
)
786 self
._nsr
_uuid
= name_uuid_map
[self
._nsr
_config
_msg
.name
]
788 self
._nsr
_msg
= nsr_msg
789 fpath
= dump_openmano_descriptor(
790 "{}_instance_sce_create".format(self
._nsr
_config
_msg
.name
),
791 self
.openmano_instance_create_yaml
,
793 self
._log
.debug("Dumped Openmano NS Scenario Cretae to: %s", fpath
)
795 self
._nsr
_uuid
= yield from self
._loop
.run_in_executor(
797 self
._cli
_api
.ns_instance_scenario_create
,
798 self
.scaling_instance_create_yaml
)
801 self
._state
= OpenmanoNSRecordState
.INSTANTIATION_PENDING
803 self
._monitor
_task
= asyncio
.ensure_future(
804 self
.instance_monitor_task(), loop
=self
._loop
808 def scaling_scenario_deploy(self
, nsr_msg
):
809 self
._log
.debug("Deploying Scaling scenario")
810 self
._nsr
_msg
= nsr_msg
811 self
._rift
_vnfd
_id
= rift_vnfd_id
812 fpath
= dump_openmano_descriptor(
813 "{}_scale_instance".format(self
._nsr
_config
_msg
.name
),
814 self
.scaling_instance_create_yaml
816 self
._state
= OpenmanoNSRecordState
.INIT
818 self
._monitor
_task
= asyncio
.ensure_future(
819 self
.instance_monitor_task(), loop
=self
._loop
825 for _
,handler
in self
._vdur
_console
_handler
.items():
826 handler
._regh
.deregister()
828 if self
._nsr
_uuid
is None:
829 self
._log
.warning("Cannot terminate an un-instantiated nsr")
832 if self
._monitor
_task
is not None:
833 self
._monitor
_task
.cancel()
834 self
._monitor
_task
= None
836 self
._log
.debug("Terminating openmano nsr")
837 yield from self
._loop
.run_in_executor(
839 self
._cli
_api
.ns_terminate
,
844 def create_vlr(self
,vlr
):
845 self
._log
.debug("Creating openmano vim network VLR name %s, VLR DC: %s",vlr
.vld_msg
.name
,
846 vlr
.om_datacenter_name
)
849 net
['name'] = vlr
.name
851 net
['type'] = 'bridge'
852 self
._log
.debug("Received ip profile is %s",vlr
._ip
_profile
)
853 if vlr
._ip
_profile
and vlr
._ip
_profile
.has_field("ip_profile_params"):
854 ip_profile_params
= vlr
._ip
_profile
.ip_profile_params
856 if ip_profile_params
.ip_version
== "ipv6":
857 ip_profile
['ip_version'] = "IPv6"
859 ip_profile
['ip_version'] = "IPv4"
860 if ip_profile_params
.has_field('subnet_address'):
861 ip_profile
['subnet_address'] = ip_profile_params
.subnet_address
862 if ip_profile_params
.has_field('gateway_address'):
863 ip_profile
['gateway_address'] = ip_profile_params
.gateway_address
864 if ip_profile_params
.has_field('dns_server') and len(ip_profile_params
.dns_server
) > 0:
865 ip_profile
['dns_address'] = ip_profile_params
.dns_server
[0].address
866 if ip_profile_params
.has_field('dhcp_params'):
867 ip_profile
['dhcp_enabled'] = ip_profile_params
.dhcp_params
.enabled
868 ip_profile
['dhcp_start_address'] = ip_profile_params
.dhcp_params
.start_address
869 ip_profile
['dhcp_count'] = ip_profile_params
.dhcp_params
.count
870 net
['ip_profile'] = ip_profile
871 net_create
["network"]= net
873 net_create_msg
= yaml
.safe_dump(net_create
,default_flow_style
=False)
874 fpath
= dump_openmano_descriptor(
875 "{}_vim_net_create_{}".format(self
._nsr
_config
_msg
.name
,vlr
.name
),
877 self
._log
.debug("Dumped Openmano VIM Net create to: %s", fpath
)
879 vim_network_uuid
= yield from self
._loop
.run_in_executor(
881 self
._cli
_api
.ns_vim_network_create
,
883 vlr
.om_datacenter_name
)
884 self
._vlrs
.append(vlr
)
889 class OpenmanoNsPlugin(rwnsmplugin
.NsmPluginBase
):
891 RW Implentation of the NsmPluginBase
893 def __init__(self
, dts
, log
, loop
, publisher
, ro_account
):
897 self
._publisher
= publisher
899 self
._http
_api
= None
900 self
._openmano
_nsrs
= {}
901 self
._vnfr
_uptime
_tasks
= {}
903 self
._set
_ro
_account
(ro_account
)
905 def _set_ro_account(self
, ro_account
):
906 self
._log
.debug("Setting openmano plugin cloud account: %s", ro_account
)
907 self
._cli
_api
= openmano_client
.OpenmanoCliAPI(
909 ro_account
.openmano
.host
,
910 ro_account
.openmano
.port
,
911 ro_account
.openmano
.tenant_id
,
914 self
._http
_api
= openmano_client
.OpenmanoHttpAPI(
916 ro_account
.openmano
.host
,
917 ro_account
.openmano
.port
,
918 ro_account
.openmano
.tenant_id
,
921 def set_state(self
, nsr_id
, state
):
922 # Currently we update only during terminate to
923 # decide how to handle VL terminate
924 if state
.value
== OpenmanoNSRecordState
.TERMINATE
.value
:
925 self
._openmano
_nsrs
[nsr_id
]._state
= \
926 [member
.value
for name
, member
in \
927 OpenmanoNSRecordState
.__members
__.items() \
928 if member
.value
== state
.value
]
930 def create_nsr(self
, nsr_config_msg
, nsd_msg
, key_pairs
=None):
932 Create Network service record
934 openmano_nsr
= OpenmanoNsr(
945 self
._openmano
_nsrs
[nsr_config_msg
.id] = openmano_nsr
948 def deploy(self
, nsr_msg
):
949 self
._log
.debug("Received NSR Deploy msg : %s", nsr_msg
)
950 openmano_nsr
= self
._openmano
_nsrs
[nsr_msg
.ns_instance_config_ref
]
951 yield from openmano_nsr
.create()
952 yield from openmano_nsr
.deploy(nsr_msg
)
955 def deploy(self
, nsr_msg
):
956 self
._log
.debug("Received Scale out msg")
957 openmano_nsr
= self
._openmano
_nsrs
[nsr_msg
.ns_instance_config_ref
]
958 yield from openmano_nsr
.scaling_scenario_create()
959 yield from openmano_nsr
.scaling_scenario_deploy(nsr_msg
)
962 def instantiate_ns(self
, nsr
, xact
):
964 Instantiate NSR with the passed nsr id
966 yield from nsr
.instantiate(xact
)
969 def instantiate_vnf(self
, nsr
, vnfr
, scaleout
=False):
971 Instantiate NSR with the passed nsr id
973 openmano_nsr
= self
._openmano
_nsrs
[nsr
.id]
975 openmano_vnf_nsr
= OpenmanoNsr(
982 openmano_nsr
.nsd_msg
,
983 openmano_nsr
.nsr_config_msg
,
984 openmano_nsr
.key_pairs
,
987 # Add new nsr to parent nsr
989 yield from openmano_nsr
.add_nsr(openmano_vnf_nsr
, vnfr
)
990 except Exception as e
:
991 self
.log
.exception("Add VNFR Error ", str(e
))
993 yield from openmano_vnf_nsr
.add_vnfr(vnfr
)
994 except Exception as e
:
995 self
.log
.exception("Scenario Create Error", str(e
))
997 yield from openmano_vnf_nsr
.create()
998 except Exception as e
:
999 self
.log
.exception("Starting instance scenario create ", str(e
))
1001 yield from openmano_vnf_nsr
.deploy(openmano_vnf_nsr
.nsr_msg
)
1002 except Exception as e
:
1003 self
.log
.exception("Unable to deploy scaling scenario ", str(e
))
1005 yield from openmano_nsr
.add_vnfr(vnfr
)
1007 # TODO: Create a task to monitor nsr/vnfr status
1008 vnfr_msg
= vnfr
.vnfr_msg
.deep_copy()
1009 vnfr_msg
.operational_status
= "init"
1011 self
._log
.debug("Attempting to publish openmano vnf: %s", vnfr_msg
)
1012 with self
._dts
.transaction() as xact
:
1013 yield from self
._publisher
.publish_vnfr(xact
, vnfr_msg
)
1014 self
._log
.debug("Creating a task to update uptime for vnfr: %s", vnfr
.id)
1015 self
._vnfr
_uptime
_tasks
[vnfr
.id] = self
._loop
.create_task(self
.vnfr_uptime_update(vnfr
))
1016 with self
._dts
.transaction() as xact
:
1017 yield from openmano_vnf_nsr
._publisher
.publish_vnfr(xact
, vnfr_msg
)
1019 def vnfr_uptime_update(self
, vnfr
):
1021 vnfr_
= RwVnfrYang
.YangData_Vnfr_VnfrCatalog_Vnfr
.from_dict({'id': vnfr
.id})
1023 vnfr_
.uptime
= int(time
.time()) - vnfr
._create
_time
1024 yield from self
._publisher
.publish_vnfr(None, vnfr_
)
1025 yield from asyncio
.sleep(2, loop
=self
._loop
)
1026 except asyncio
.CancelledError
:
1027 self
._log
.debug("Received cancellation request for vnfr_uptime_update task")
1030 def instantiate_vl(self
, nsr
, vlr
):
1032 Instantiate NSR with the passed nsr id
1034 self
._log
.debug("Received instantiate VL for NSR {}; VLR {}".format(nsr
.id,vlr
))
1035 openmano_nsr
= self
._openmano
_nsrs
[nsr
.id]
1036 if openmano_nsr
._state
== OpenmanoNSRecordState
.RUNNING
:
1037 yield from openmano_nsr
.create_vlr(vlr
)
1038 yield from self
._publisher
.publish_vlr(None, vlr
.vlr_msg
)
1040 yield from openmano_nsr
.add_vlr(vlr
)
1043 def terminate_ns(self
, nsr
):
1045 Terminate the network service
1048 openmano_nsr
= self
._openmano
_nsrs
[nsr_id
]
1050 yield from openmano_nsr
.terminate()
1051 yield from openmano_nsr
.delete()
1053 with self
._dts
.transaction() as xact
:
1054 for vnfr
in openmano_nsr
.vnfrs
:
1055 self
._log
.debug("Unpublishing VNFR: %s", vnfr
.vnfr
.vnfr_msg
)
1056 yield from self
._publisher
.unpublish_vnfr(xact
, vnfr
.vnfr
.vnfr_msg
)
1058 del self
._openmano
_nsrs
[nsr_id
]
1061 def terminate_vnf(self
, vnfr
):
1063 Terminate the network service
1065 if vnfr
.id in self
._vnfr
_uptime
_tasks
:
1066 self
._vnfr
_uptime
_tasks
[vnfr
.id].cancel()
1069 def terminate_vl(self
, vlr
):
1071 Terminate the virtual link
1073 self
._log
.debug("Received terminate VL for VLR {}".format(vlr
))
1074 openmano_nsr
= self
._openmano
_nsrs
[vlr
._nsr
_id
]
1075 if openmano_nsr
._state
== OpenmanoNSRecordState
.RUNNING
:
1076 yield from openmano_nsr
.delete_vlr(vlr
)
1078 yield from openmano_nsr
.remove_vlr(vlr
)