def cb_create(self, tctx, root, service, proplist): self.tctx = tctx self.root = root self.service = service self.proplist = proplist self.template = ncs.template.Template(self.service) self.log.info("ns-info") self.self_plan = PlanComponent(service, 'self', 'ncs:self') self.self_plan.append_state('ncs:init') self.self_plan.append_state('ncs:ready') self.self_plan.set_reached('ncs:init') self.nsd = root.nfvo_rel2__nfvo.nsd[service.nsd] if not service.flavor: raise Exception("Must specify NSD deployment flavor") self.log.info("NSD deployment-flavor {}".format(service.flavor)) self.deployment_flavor = self.nsd.deployment_flavor[service.flavor] # Find the scaling aspect and from it, the instantiation level if not service.instantiation_level: raise Exception("Must specify instantiation level") inst_level = self.deployment_flavor.instantiation_level[ service.instantiation_level] for vl2level in inst_level.vl_to_level_mapping: self._create_vl(vl2level) for vnf2level in inst_level.vnf_to_level_mapping: self._create_vnf(vnf2level) with ncs.maapi.single_read_trans(tctx.username, tctx.context, db=ncs.OPERATIONAL) as oper_th: oroot = ncs.maagic.get_root(oper_th) vnf_deployment = oroot.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment if not (service.tenant, service.deployment_name, service.esc) in vnf_deployment: self.log.info("VNF not yet ready") return dep = oroot.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment[ service.tenant, service.deployment_name, service.esc] plan = dep.plan self.copy_vdu_plans(plan) if plan.failed: self.log.error( "VNF %s/%s/%s has failed" % (service.tenant, service.deployment_name, service.esc)) self.self_plan.set_failed('ncs:ready') return ready_status = str(plan.component['self'].state['ready'].status) if 'reached' != ready_status: self.log.info("VNF not yet ready") return self.self_plan.set_reached('ncs:ready')
def setup_plan(self, result, router): test_plan = PlanComponent( result, '%s --> %s' % (self.router_name, router.name), 'destination-test') (__, do_cef_validation, do_ping_test) = self.options test_plan.append_state('adjacency-sids-validation') test_plan.append_state('prefix-sid-validation') if do_cef_validation: test_plan.append_state('cef-validation') if do_ping_test: test_plan.append_state('ping-test') return test_plan.component._path
def cb_create(self, tctx, root, service, proplist): self.log.info("VNF") self.service = service self.root = root self.self_plan = PlanComponent(service, 'self', 'ncs:self') self.self_plan.append_state('ncs:init') self.self_plan.append_state('ncs:ready') self.self_plan.set_reached('ncs:init') vdu_plans = [] any_failed = [] self.log.debug("Running....") for vnf_info in service.vnf_info: validate_config(validate_vnfd_existance, (root, vnf_info.vnfd)) vnfd = root.nfvo_rel2__nfvo.vnfd[vnf_info.vnfd] self.log.info('VNF %s' % (vnf_info.name)) for vdu in vnfd_flavour_vdus(vnf_info, vnfd): validate_config(validate_ned_for_managed_interface, (vnfd, vnf_info, vdu)) (vdu_ready, failed) = \ self._apply_per_vdu_instance(vnfd, vnf_info, vdu) vdu_plans.append(vdu_ready) any_failed.append(failed) all_vdus_ready = all(vdu_plans) and len(vdu_plans) > 0 if all_vdus_ready: self.self_plan.set_reached('ncs:ready') res_l = self.root.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment_result dpr_key = (self.service.tenant, self.service.deployment_name, self.service.esc) if dpr_key in res_l: if res_l[dpr_key].status.error or any(any_failed): self.log.info( "Failed getting to state 'ready' for {}".format(dpr_key)) self.self_plan.set_failed('ncs:ready')
def wrapper(self, tctx, root, service, proplist): self.log.info('Service create ({})'.format(service._path)) self_plan = init_plan(PlanComponent(service, 'self', 'ncs:self'), *custom_states) try: proplist = cb_create_method(self, tctx, root, service, proplist, self_plan) if proplist is None: return except NcsServiceError as e: self.log.error(e) self_plan.set_failed('ncs:ready') else: self_plan.set_reached('ncs:ready') return proplist
class NSInfo(Service): @Service.create def cb_create(self, tctx, root, service, proplist): self.tctx = tctx self.root = root self.service = service self.proplist = proplist self.template = ncs.template.Template(self.service) self.log.info("ns-info") self.self_plan = PlanComponent(service, 'self', 'ncs:self') self.self_plan.append_state('ncs:init') self.self_plan.append_state('ncs:ready') self.self_plan.set_reached('ncs:init') self.nsd = root.nfvo_rel2__nfvo.nsd[service.nsd] if not service.flavor: raise Exception("Must specify NSD deployment flavor") self.log.info("NSD deployment-flavor {}".format(service.flavor)) self.deployment_flavor = self.nsd.deployment_flavor[service.flavor] # Find the scaling aspect and from it, the instantiation level if not service.instantiation_level: raise Exception("Must specify instantiation level") inst_level = self.deployment_flavor.instantiation_level[ service.instantiation_level] for vl2level in inst_level.vl_to_level_mapping: self._create_vl(vl2level) for vnf2level in inst_level.vnf_to_level_mapping: self._create_vnf(vnf2level) with ncs.maapi.single_read_trans(tctx.username, tctx.context, db=ncs.OPERATIONAL) as oper_th: oroot = ncs.maagic.get_root(oper_th) vnf_deployment = oroot.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment if not (service.tenant, service.deployment_name, service.esc) in vnf_deployment: self.log.info("VNF not yet ready") return dep = oroot.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment[ service.tenant, service.deployment_name, service.esc] plan = dep.plan self.copy_vdu_plans(plan) if plan.failed: self.log.error( "VNF %s/%s/%s has failed" % (service.tenant, service.deployment_name, service.esc)) self.self_plan.set_failed('ncs:ready') return ready_status = str(plan.component['self'].state['ready'].status) if 'reached' != ready_status: self.log.info("VNF not yet ready") return self.self_plan.set_reached('ncs:ready') def _create_vnf(self, vnf2level): self.log.info("_create_vnf %s" % (vnf2level.vnf_profile)) vnf_profile = self.deployment_flavor.vnf_profile[vnf2level.vnf_profile] vnfd_name = vnf_profile.vnfd vnfd_deployment_flavor = vnf_profile.flavor vnfd_instantiation_level = vnf_profile.instantiation_level self.log.info( "_create_vnf %s/%s/%s" % (vnfd_name, vnfd_deployment_flavor, vnfd_instantiation_level)) # First copy all VDU settings vars = ncs.template.Variables() vars.add('VNF_PROFILE_NAME', vnf_profile.id) vars.add('VNF_NAME', vnfd_name) vars.add('VNF_FLAVOR', vnfd_deployment_flavor) vars.add('VNF_IL', vnfd_instantiation_level) self.template.apply( 'tailf-etsi-rel2-nfvo-esc-ns-info-copy-to-vnf-info', vars) # Setup the VNF's interfaces for sapd_con in vnf_profile.sapd_connectivity: sapd_name = sapd_con.sapd # Figure out the network name for this sapd network_name = self.service.sap_info[sapd_name].network_name vnf_cp = sapd_con.cp self.log.debug("SAPD: %s <-> %s on VLR %s" % (sapd_name, vnf_cp, network_name)) vars.add('VNF_CP', vnf_cp) vars.add('NETWORK_NAME', network_name) self.template.apply( 'tailf-etsi-rel2-nfvo-esc-ns-info-vnfd-connection-point', vars) for vl_con in vnf_profile.virtual_link_connectivity: vlp_name = vl_con.virtual_link_profile vl_profile = self.deployment_flavor.virtual_link_profile[vlp_name] vld_name = vl_profile.virtual_link_descriptor vlr = self._vlr_name(vld_name) vnf_cp = vl_con.cp self.log.debug("VLP: %s <-> %s on VLR %s" % (vld_name, vnf_cp, vlr)) vars.add('VNF_CP', vnf_cp) vars.add('NETWORK_NAME', vlr) self.template.apply( 'tailf-etsi-rel2-nfvo-esc-ns-info-vnfd-connection-point', vars) def _create_vl(self, vl2level): vlp_name = vl2level.virtual_link_profile self.log.info("_create_vl %s" % (vlp_name)) vl_profile = self.deployment_flavor.virtual_link_profile[vlp_name] vl_info = self.service.virtual_link_info[ vl_profile.virtual_link_descriptor] vars = ncs.template.Variables() vars.add('NW', self._vlr_name(vl_info.virtual_link_descriptor)) vars.add('NS_VLD', vl_info.virtual_link_descriptor) self.template.apply('tailf-etsi-rel2-nfvo-esc-ns-info-nw', vars) def _vlr_name(self, ns_vld_name): vlr = "%s-%s-%s" % (self.service.tenant, self.service.deployment_name, ns_vld_name) return vlr def copy_vdu_plans(self, vnfr_plan): for vdu_plan in vnfr_plan.component: if 'self' == str(vdu_plan.name): continue plan = PlanComponent(self.service, vdu_plan.name, 'nfvo-rel2-esc:vdu') plan.append_state('ncs:init') plan.append_state('nfvo-rel2-esc:deployed') plan.append_state('ncs:ready') for state in vdu_plan.state: if 'reached' == str(state.status): plan.set_reached(state.name) elif 'failed' == str(state.status): plan.set_failed(state.name)
def copy_vdu_plans(self, vnfr_plan): for vdu_plan in vnfr_plan.component: if 'self' == str(vdu_plan.name): continue plan = PlanComponent(self.service, vdu_plan.name, 'nfvo-rel2-esc:vdu') plan.append_state('ncs:init') plan.append_state('nfvo-rel2-esc:deployed') plan.append_state('ncs:ready') for state in vdu_plan.state: if 'reached' == str(state.status): plan.set_reached(state.name) elif 'failed' == str(state.status): plan.set_failed(state.name)
def cb_create(self, tctx, root, service, proplist): self.log.info('Service create(service=', service._path, ')') plan = PlanComponent(service, "self", "ncs:self") plan.append_state("ncs:init") plan.append_state("topology-nodes:device-onboarding") plan.append_state("topology-nodes:fetch-sshkey") plan.append_state("topology-nodes:sync-from") plan.append_state("topology-nodes:day0-config") plan.append_state("ncs:ready") plan.set_reached("ncs:init") template = ncs.template.Template(service) try: template.apply('onboarding-node') except Exception as e: self.log.error("Onboarding node failed : " + str(e)) plan.set_failed("topology-nodes:device-onboarding") return if not check_device(service): template.apply('device-onboarding-kicker') return plan.set_reached("topology-nodes:device-onboarding") try: with ncs.maapi.single_write_trans('admin', 'admin', groups=['ncsadmin']) as t: root = ncs.maagic.get_root(t) device = root.devices.device[service.name] output = device.ssh.fetch_host_keys() self.log.info('[{}]fetch result: {}'.format( service.name, output.result)) t.apply() except Exception as e: self.log.error("Fetching ssh key failed : " + str(e)) plan.set_failed("topology-nodes:fetch-sshkey") return plan.set_reached("topology-nodes:fetch-sshkey") try: with ncs.maapi.single_write_trans('admin', 'admin', groups=['ncsadmin']) as t: root = ncs.maagic.get_root(t) device = root.devices.device[service.name] output = device.sync_from() self.log.info('Sync-from result: {}'.format(output.result)) t.apply() except Exception as e: self.log.error("Sync-From failed : " + str(e)) plan.set_failed("topology-nodes:sync-from") return plan.set_reached("topology-nodes:sync-from") pool_name = "deviceLoopbacks" allocation_name = service.name + "Loopback" ip_allocator.net_request( service, "/topology-nodes:topology-nodes[name='%s']" % (service.name), tctx.username, pool_name, allocation_name, 32) loopback_ip = ip_allocator.net_read(tctx.username, root, pool_name, allocation_name) if not loopback_ip: self.log.info("Alloc not ready") return vars = ncs.template.Variables() vars.add('loopback_ip', loopback_ip) vars.add('ASN', AS_No) template = ncs.template.Template(service) template.apply('day0-config', vars) plan.set_reached("topology-nodes:day0-config") plan.set_reached("ncs:ready")
def cb_create(self, tctx, root, service, proplist): template = ncs.template.Template(service) variables = ncs.template.Variables() # 1 Create initial PLAN states for our service plan = PlanComponent(service, "self", "ncs:self") plan.append_state("ncs:init") plan.append_state("ourservice-python:allocation") plan.append_state("ourservice-python:vm-run") plan.append_state("ourservice-python:vm-config") plan.append_state("ncs:ready") plan.set_reached("ncs:init") # 2 Create allocation template.apply('ourservice-python-ro-template') # if no RO, create kicker on ro result # 3 Wait for allocation to be ready if not is_allocation_ready(tctx, service.allocation): template.apply('ourservice-python-ro-kicker-template') return plan.set_reached("ourservice-python:allocation") # 4 Get allocation response data and use it to instantiate a VNF-INFO host, vnfm = get_allocation_info(tctx, service.allocation) vnfinfo = "{}-csr".format(service.name) variables.add("HOST", host) variables.add("VNFM", vnfm) variables.add("VNF", vnfinfo) template.apply('ourservice-python-vnf-info-template', variables) # 5 Wait for the VNF to be up and running if not is_vnf_ready(root, vnfinfo): template.apply('ourservice-python-vnf-info-kicker-template') return # 6 Configure the device and update our PLAN that the device is # up and configured plan.set_reached("ourservice-python:vm-run") template.apply('ourservice-python-csr-template') plan.set_reached("ourservice-python:vm-config") # 7 Fetch some operational data from the device and store it in our service info = VnfInfo(vnfinfo, root) device = iter(info.get_created_devices_per_vdu()['CSR']).next() for i in device.interface: s_interface = service.operdata.GigabitEthernet.create(i.nic_id+1) s_interface.address = i.ip_address s_interface.mac = i.mac_address s_interface.gateway = i.gateway # Mark service ready plan.set_reached("ncs:ready")
def configure_network_service(self, tctx, root, service, network_service): self.log.info('Configuring NFVO: ', network_service.name) nfvo_helper = NfvoHelper(self.log, tctx, root, service, network_service) topology_conn_count = sum( 1 for connection in nfvo_helper.topology_connections if connection.device is not None) ns_plan = PlanComponent(service, network_service.name, 'tme-demo:network-service') ns_plan.append_state('ncs:init') ns_plan.append_state('tme-demo:ip-addresses-allocated') ns_plan.append_state('tme-demo:vnfs-instantiated') if topology_conn_count > 0: ns_plan.append_state('tme-demo:topology-created') ns_plan.append_state('ncs:ready') ns_plan.set_reached('ncs:init') if nfvo_helper.allocate_ip_addresses(): ns_plan.set_reached('tme-demo:ip-addresses-allocated') else: self.log.info('IP addresses not ready') return False if nfvo_helper.configure_network_service(): ns_plan.set_reached('tme-demo:vnfs-instantiated') else: self.log.info('ns-info not ready') return False if topology_conn_count > 0: nfvo_helper.configure_topology_connections() ns_plan.set_reached('tme-demo:topology-created') ns_plan.set_reached('ncs:ready') return True
def cb_create(self, tctx, root, service, proplist): self.log.info('Service create(service=', service._path, ')') self_plan = PlanComponent(service, 'self', 'ncs:self') self_plan.append_state('ncs:init') self_plan.append_state('ncs:ready') self_plan.set_reached('ncs:init') ns_ready_count = sum( 1 for network_service in service.nfvo.network_service if self.configure_network_service(tctx, root, service, network_service)) if service.l3vpn.exists(): self.log.info('Configuring L3VPN') l3vpn_plan = PlanComponent(service, 'l3vpn', 'tme-demo:l3vpn') l3vpn_plan.append_state('ncs:init') l3vpn_plan.append_state('ncs:ready') l3vpn_plan.set_reached('ncs:init') template = ncs.template.Template(service) template.apply('l3vpn') l3vpn_plan.set_reached('ncs:ready') if service.data_centre.exists(): self.log.info('Configuring data-centre connectivity') data_centre_plan = PlanComponent(service, 'data-centre', 'tme-demo:data-centre') data_centre_plan.append_state('ncs:init') data_centre_plan.append_state('ncs:ready') data_centre_plan.set_reached('ncs:init') template = ncs.template.Template(service) template.apply('data-centre') data_centre_plan.set_reached('ncs:ready') if len(service.nfvo.network_service) == ns_ready_count: self_plan.set_reached('ncs:ready') self.log.info('Service ready')
def _apply_per_vdu_instance(self, vnfd, vnf_info, vdu): plan_name = vnf_info.name + "-" + vdu.id plan = PlanComponent(self.service, plan_name, 'nfvo-rel2-esc:vdu') plan.append_state('ncs:init') plan.append_state('nfvo-rel2-esc:deployed') plan.append_state('ncs:ready') plan.set_reached('ncs:init') dpr_key = (self.service.tenant, self.service.deployment_name, self.service.esc) vdu_key = (vnf_info.name, vdu.id) res_l = self.root.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment_result (min_active, max_active) = _get_min_max_number_of_instances(vnfd, vnf_info, vdu) ready = False failed = False if dpr_key in res_l and vdu_key in res_l[dpr_key].vdu: vm_devices = res_l[dpr_key].vdu[vdu_key].vm_device deployed = sum(bool(d.status.deployed) for d in vm_devices) >= min_active ready = sum(bool(d.status.ready) for d in vm_devices) >= min_active any_error = any(bool(d.status.error) for d in vm_devices) if (deployed or ready) and not any_error: # we are always deployed if we are ready plan.set_reached('nfvo-rel2-esc:deployed') if ready: plan.set_reached('ncs:ready') if any_error: ready = False failed = True plan.set_failed('ncs:ready') return (ready, failed)
class VNF(Service): """ Implements the service point 'tailf-etsi-rel2-nfvo-esc-vnf-info', which is called when config is written to /nfvo-rel2:nfvo/vnf-info/esc/vnf-deployment . Do remember to look at the vnf_subcsriber to see how the vnf-deployment is handled. """ @Service.create def cb_create(self, tctx, root, service, proplist): self.log.info("VNF") self.service = service self.root = root self.self_plan = PlanComponent(service, 'self', 'ncs:self') self.self_plan.append_state('ncs:init') self.self_plan.append_state('ncs:ready') self.self_plan.set_reached('ncs:init') vdu_plans = [] any_failed = [] self.log.debug("Running....") for vnf_info in service.vnf_info: validate_config(validate_vnfd_existance, (root, vnf_info.vnfd)) vnfd = root.nfvo_rel2__nfvo.vnfd[vnf_info.vnfd] self.log.info('VNF %s' % (vnf_info.name)) for vdu in vnfd_flavour_vdus(vnf_info, vnfd): validate_config(validate_ned_for_managed_interface, (vnfd, vnf_info, vdu)) (vdu_ready, failed) = \ self._apply_per_vdu_instance(vnfd, vnf_info, vdu) vdu_plans.append(vdu_ready) any_failed.append(failed) all_vdus_ready = all(vdu_plans) and len(vdu_plans) > 0 if all_vdus_ready: self.self_plan.set_reached('ncs:ready') res_l = self.root.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment_result dpr_key = (self.service.tenant, self.service.deployment_name, self.service.esc) if dpr_key in res_l: if res_l[dpr_key].status.error or any(any_failed): self.log.info( "Failed getting to state 'ready' for {}".format(dpr_key)) self.self_plan.set_failed('ncs:ready') def _apply_per_vdu_instance(self, vnfd, vnf_info, vdu): plan_name = vnf_info.name + "-" + vdu.id plan = PlanComponent(self.service, plan_name, 'nfvo-rel2-esc:vdu') plan.append_state('ncs:init') plan.append_state('nfvo-rel2-esc:deployed') plan.append_state('ncs:ready') plan.set_reached('ncs:init') dpr_key = (self.service.tenant, self.service.deployment_name, self.service.esc) vdu_key = (vnf_info.name, vdu.id) res_l = self.root.nfvo_rel2__nfvo.vnf_info.esc.vnf_deployment_result (min_active, max_active) = _get_min_max_number_of_instances(vnfd, vnf_info, vdu) ready = False failed = False if dpr_key in res_l and vdu_key in res_l[dpr_key].vdu: vm_devices = res_l[dpr_key].vdu[vdu_key].vm_device deployed = sum(bool(d.status.deployed) for d in vm_devices) >= min_active ready = sum(bool(d.status.ready) for d in vm_devices) >= min_active any_error = any(bool(d.status.error) for d in vm_devices) if (deployed or ready) and not any_error: # we are always deployed if we are ready plan.set_reached('nfvo-rel2-esc:deployed') if ready: plan.set_reached('ncs:ready') if any_error: ready = False failed = True plan.set_failed('ncs:ready') return (ready, failed)
def cb_create(self, tctx, root, service, proplist): self.log.info('Service create(service=', service._path, ')') self_plan = PlanComponent(service, 'self', 'ncs:self') self_plan.append_state('ncs:init') self_plan.append_state('ncs:ready') self_plan.set_reached('ncs:init') ready_count = 0 igp_domain = root.sr_migrate__igp_domain[service.igp_domain] for router in igp_domain.router: router_plan = PlanComponent(service, router.name, 'sr-migrate:router-migration') router_plan.append_state('ncs:init') router_plan.append_state('sr-migrate:segment-routing-enabled') router_plan.append_state('sr-migrate:connectivity-test') router_plan.append_state('sr-migrate:sr-imposition-preferred') router_plan.append_state('sr-migrate:label-imposition-test') router_plan.append_state('sr-migrate:ldp-disabled') router_plan.append_state('ncs:ready') router_plan.set_reached('ncs:init') requested_prefix_sid = -1 if router.custom_prefix_sid: requested_prefix_sid = router.custom_prefix_sid allocation_name = '%s-%s' % (service.igp_domain, router.name) id_allocator.id_request( service, "/ncs:services/sr-migrate:sr-migrate" + "[sr-migrate:igp-domain='%s']" % service.igp_domain, tctx.username, igp_domain.sid_pool, allocation_name, False, requested_prefix_sid ) prefix_sid = id_allocator.id_read( tctx.username, root, igp_domain.sid_pool, allocation_name) if not prefix_sid: self.log.info('Prefix-sid for router %s not ready' % router.name) continue self.log.info('Allocated prefix-sid %d for router %s' % (prefix_sid, router.name)) router.prefix_sid = prefix_sid if service.enable_segment_routing: template = ncs.template.Template(router) template.apply('enable-segment-routing') router_plan.set_reached('sr-migrate:segment-routing-enabled') ready_count += 1 if ready_count != len(igp_domain.router.keys()): return igp_domain.sr_migrate_test_request.create('connectivity-test') if not check_test_results(service.connectivity_test_results, 'sr-migrate:connectivity-test'): self.log.info('Connectivity test not passed') return if service.prefer_sr_imposition: for router in igp_domain.router: template = ncs.template.Template(router) template.apply('prefer-sr-imposition') set_plan_reached(service, router, 'sr-migrate:sr-imposition-preferred') igp_domain.sr_migrate_test_request.create('label-imposition-test') if not check_test_results(service.label_imposition_test_results, 'sr-migrate:label-imposition-test'): self.log.info('Label imposition test not passed') return if service.disable_ldp: for router in igp_domain.router: disable_ldp(root, igp_domain) set_plan_reached(service, router, 'sr-migrate:ldp-disabled') set_plan_reached(service, router, 'ncs:ready') self_plan.set_reached('ncs:ready') self.log.info('Service ready - %s migration complete' % (service.igp_domain))