def handle(self, env, values): router = values['payload']['router'] host_id = values["publisher_id"].replace("network.", "", 1) project_id = values['_context_project_id'] router_id = encode_router_id(router['id']) host = self.inv.get_by_id(env, host_id) fetcher = CliFetchHostVservice() fetcher.set_env(env) router_doc = fetcher.get_vservice(host_id, router_id) gateway_info = router['external_gateway_info'] if gateway_info: network_id = gateway_info['network_id'] self.add_router_document(env, network_id, router_doc, host) self.add_children_documents(env, project_id, network_id, host, router_doc) else: self.add_router_document(env, None, router_doc, host) # scan links and cliques FindLinksForVserviceVnics().add_links(search={"parent_id": router_id}) scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() self.log.info("Finished router added.") return EventResult(result=True, related_object=router_id, display_context=router_id)
def handle(self, env, values): # find the host, to serve as parent instance_id = values['payload']['instance_id'] host_id = values['payload']['host'] instances_root_id = host_id + '-instances' instances_root = self.inv.get_by_id(env, instances_root_id) if not instances_root: self.log.info('instances root not found, aborting instance add') return EventResult(result=False, retry=True) # scan instance scanner = Scanner() scanner.set_env(env) scanner.scan("ScanInstancesRoot", instances_root, limit_to_child_id=instance_id, limit_to_child_type='instance') scanner.scan_from_queue() # scan host host = self.inv.get_by_id(env, host_id) scanner.scan( 'ScanHost', host, limit_to_child_type=['vconnectors_folder', 'vedges_folder']) scanner.scan_from_queue() scanner.scan_links() scanner.scan_cliques() return EventResult(result=True, related_object=instance_id, display_context=instance_id)
def handle(self, env, notification): # check for network document. subnet = notification['payload']['subnet'] project_id = subnet['tenant_id'] network_id = subnet['network_id'] if 'id' not in subnet: self.log.info( 'Subnet payload doesn\'t have id, aborting subnet add') return EventResult(result=False, retry=False) network_document = self.inv.get_by_id(env, network_id) if not network_document: self.log.info( 'network document does not exist, aborting subnet add') return EventResult(result=False, retry=True) network_name = network_document['name'] # build subnet document for adding network if subnet['cidr'] not in network_document['cidrs']: network_document['cidrs'].append(subnet['cidr']) if not network_document.get('subnets'): network_document['subnets'] = {} network_document['subnets'][subnet['name']] = subnet if subnet['id'] not in network_document['subnet_ids']: network_document['subnet_ids'].append(subnet['id']) self.inv.set(network_document) # Check DHCP enable, if true, scan network. if subnet['enable_dhcp'] is True: # update network if not ApiAccess.regions: fetcher = ApiFetchRegions() fetcher.set_env(env) fetcher.get(project_id) self.log.info("add new subnet.") host_id = notification["publisher_id"].replace("network.", "", 1) self.add_children_documents(env, project_id, network_id, network_name, host_id) # scan links and cliques self.log.info("scanning for links") FindLinksForPnics().add_links() FindLinksForVserviceVnics().add_links( search={"parent_id": "qdhcp-%s-vnics" % network_id}) scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() self.log.info("Finished subnet added.") return EventResult(result=True, related_object=subnet['id'], display_context=network_id)
def run(self, args: dict = None): args = setup_args(args, self.DEFAULTS, self.get_args) # After this setup we assume args dictionary has all keys # defined in self.DEFAULTS self.log.set_loglevel(args['loglevel']) try: MongoAccess.set_config_file(args['mongo_config']) self.inv = InventoryMgr() self.inv.log.set_loglevel(args['loglevel']) self.inv.set_collections(args['inventory']) self.conf = Configuration() except FileNotFoundError as e: return False, 'Mongo configuration file not found: {}'\ .format(str(e)) scan_plan = self.get_scan_plan(args) if scan_plan.clear or scan_plan.clear_all: self.inv.clear(scan_plan) self.conf.log.set_loglevel(scan_plan.loglevel) env_name = scan_plan.env self.conf.use_env(env_name) # generate ScanObject Class and instance. scanner = Scanner() scanner.log.set_loglevel(args['loglevel']) scanner.set_env(env_name) scanner.found_errors[env_name] = False # decide what scanning operations to do inventory_only = scan_plan.inventory_only links_only = scan_plan.links_only cliques_only = scan_plan.cliques_only monitoring_setup_only = scan_plan.monitoring_setup_only run_all = False if inventory_only or links_only or cliques_only \ or monitoring_setup_only else True # setup monitoring server monitoring = \ self.inv.is_feature_supported(env_name, EnvironmentFeatures.MONITORING) if monitoring: self.inv.monitoring_setup_manager = \ MonitoringSetupManager(env_name) self.inv.monitoring_setup_manager.server_setup() # do the actual scanning try: if inventory_only or run_all: scanner.run_scan(scan_plan.scanner_type, scan_plan.obj, scan_plan.id_field, scan_plan.child_id, scan_plan.child_type) if links_only or run_all: scanner.scan_links() if cliques_only or run_all: scanner.scan_cliques() if monitoring: if monitoring_setup_only: self.inv.monitoring_setup_manager.simulate_track_changes() if not (inventory_only or links_only or cliques_only): scanner.deploy_monitoring_setup() except ScanError as e: return False, "scan error: " + str(e) SshConnection.disconnect_all() status = 'ok' if not scanner.found_errors.get(env_name, False) \ else 'errors detected' if status == 'ok' and scan_plan.object_type == "environment": self.mark_env_scanned(scan_plan.env) self.log.info('Scan completed, status: {}'.format(status)) return True, status
def handle(self, env, notification): project = notification['_context_project_name'] project_id = notification['_context_project_id'] payload = notification['payload'] port = payload['port'] network_id = port['network_id'] network_name = self.get_name_by_id(network_id) mac_address = port['mac_address'] # check ports folder document. ports_folder = self.inv.get_by_id(env, network_id + '-ports') if not ports_folder: self.log.info("ports folder not found, add ports folder first.") self.add_ports_folder(env, project_id, network_id, network_name) self.add_port_document(env, project, project_id, network_name, network_id, port) # update the port related documents. if 'compute' in port['device_owner']: # update the instance related document. host_id = port['binding:host_id'] instance_id = port['device_id'] old_instance_doc = self.inv.get_by_id(env, instance_id) instances_root_id = host_id + '-instances' instances_root = self.inv.get_by_id(env, instances_root_id) if not instances_root: self.log.info( 'instance document not found, aborting port adding') return EventResult(result=False, retry=True) # update instance instance_fetcher = ApiFetchHostInstances() instance_fetcher.set_env(env) instance_docs = instance_fetcher.get(host_id + '-') instance = next( filter(lambda i: i['id'] == instance_id, instance_docs), None) if instance: old_instance_doc['network_info'] = instance['network_info'] old_instance_doc['network'] = instance['network'] if old_instance_doc.get('mac_address') is None: old_instance_doc['mac_address'] = mac_address self.inv.set(old_instance_doc) self.log.info("update instance document") # add vnic document. if port['binding:vif_type'] == 'vpp': vnic_fetcher = CliFetchInstanceVnicsVpp() else: # set ovs as default type. vnic_fetcher = CliFetchInstanceVnics() vnic_fetcher.set_env(env) vnic_docs = vnic_fetcher.get(instance_id + '-') vnic = next( filter(lambda vnic: vnic['mac_address'] == mac_address, vnic_docs), None) if vnic: vnic['environment'] = env vnic['type'] = 'vnic' vnic['name_path'] = old_instance_doc[ 'name_path'] + '/vNICs/' + vnic['name'] vnic['id_path'] = '{}/{}/{}'.format( old_instance_doc['id_path'], old_instance_doc['id'], vnic['name']) self.inv.set(vnic) self.log.info( "add instance-vnic document, mac_address: {}".format( mac_address)) self.log.info("scanning for links") fetchers_implementing_add_links = [ FindLinksForInstanceVnics(), FindLinksForVedges() ] for fetcher in fetchers_implementing_add_links: fetcher.add_links() scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() port_document = self.inv.get_by_id(env, port['id']) if not port_document: self.log.error("Port {} failed to add".format(port['id'])) return EventResult(result=False, retry=True) return EventResult(result=True, related_object=port['id'], display_context=network_id)
def handle(self, env, values): interface = values['payload']['router_interface'] project_id = values['_context_project_id'] project = values['_context_project_name'] host_id = values["publisher_id"].replace("network.", "", 1) port_id = interface['port_id'] subnet_id = interface['subnet_id'] router_id = encode_router_id(interface['id']) network_document = self.inv.get_by_field(env, "network", "subnet_ids", subnet_id, get_single=True) if not network_document: self.log.info("network document not found, aborting interface adding") return EventResult(result=False, retry=True) network_name = network_document['name'] network_id = network_document['id'] # add router-interface port document. if not ApiAccess.regions: fetcher = ApiFetchRegions() fetcher.set_env(env) fetcher.get(project_id) port_doc = EventSubnetAdd().add_port_document(env, port_id, network_name=network_name) mac_address = port_doc['mac_address'] if port_doc else None # add vnic document host = self.inv.get_by_id(env, host_id) router_doc = self.inv.get_by_id(env, router_id) add_vnic_document = partial(EventPortAdd().add_vnic_document, env=env, host=host, object_id=interface['id'], object_type='router', network_name=network_name, router_name=router_doc['name'], mac_address=mac_address) ret = add_vnic_document() if ret is False: # try it again to fetch vnic document, vnic will be created a little bit late before CLI fetch. time.sleep(self.delay) self.log.info("Wait {} seconds, and then fetch vnic document again.".format(self.delay)) add_vnic_document() # update the router document: gw_port_id, network. self.update_router(env, project, network_id, network_name, router_doc, host_id) # update vservice-vnic, vnic-network, FindLinksForVserviceVnics().add_links(search={"parent_id": router_id}) scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() self.log.info("Finished router-interface added.") return EventResult(result=True, related_object=interface['id'], display_context=network_id)
class TestScanner(TestScan): def setUp(self): super().setUp() ScanMetadataParser.parse_metadata_file = \ MagicMock(return_value=METADATA) FindLinksMetadataParser.parse_metadata_file = \ MagicMock(return_value=LINK_FINDERS_METADATA) self.scanner = Scanner() self.scanner.set_env(self.env) MonitoringSetupManager.create_setup = MagicMock() self.scanner.inv.monitoring_setup_manager = \ MonitoringSetupManager(self.env) def test_check_type_env_without_environment_condition(self): result = self.scanner.check_type_env(TYPE_TO_FETCH_WITHOUT_ENV_CON) self.assertEqual( result, True, "Can't get true when the type_to_fetch " + "doesn't contain environment condition") def test_check_type_with_error_value(self): # store original method original_get_env_config = self.scanner.config.get_env_config # mock get_env_config method self.scanner.config.get_env_config =\ MagicMock(return_value=CONFIGURATIONS) result = self.scanner.check_type_env(TYPE_TO_FETCH_WITH_ERROR_VALUE) # reset get_env_config method self.scanner.config.get_env_config = original_get_env_config self.assertEqual( result, False, "Can't get false when the type_to_fetch " + "contain error value") def test_check_type_env_without_mechanism_drivers_in_env_config(self): # store original method original_get_env_config = self.scanner.config.get_env_config # mock get_env_config_method self.scanner.config.get_env_config =\ MagicMock(return_value=CONFIGURATIONS_WITHOUT_MECHANISM_DRIVERS) result = self.scanner.check_type_env(TYPE_TO_FETCH) # reset get_env_config method self.scanner.check_type_env = original_get_env_config self.assertEqual( result, False, "Can't get false when configuration " + "doesn't contain mechanism drivers") def test_check_type_env_with_wrong_mech_drivers_in_env_condition(self): # store original method original_get_env_config = self.scanner.config.get_env_config # mock get_env_config_method self.scanner.config.get_env_config =\ MagicMock(return_value=CONFIGURATIONS) result = self.scanner.\ check_type_env(TYPE_TO_FETCH_WITH_WRONG_ENVIRONMENT_CONDITION) # reset get_env_config method self.scanner.check_type_env = original_get_env_config self.assertEqual( result, False, "Can't get false when the mechanism " + "drivers in type_to_fetch " + "don't exist in configurations") def test_check_type_env(self): # store original method original_get_env_config = self.scanner.config.get_env_config # mock method self.scanner.config.get_env_config =\ MagicMock(return_value=CONFIGURATIONS) result = self.scanner.check_type_env(TYPE_TO_FETCH) # reset method self.scanner.config.get_env_config = original_get_env_config self.assertEqual(result, True, "Can't get True when the type_to_fetch is correct") def test_scan_error_type(self): # store original method original_check_type_env = self.scanner.check_type_env # mock method self.scanner.check_type_env = MagicMock(return_value=False) result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) # reset method self.scanner.check_type_env = original_check_type_env self.assertEqual(result, [], "Can't get [], when the type_to_fetch is wrong") def test_scan_type_without_parent_id(self): try: self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT_WITHOUT_ID, ID_FIELD) self.fail("Can't get error when the parent " + "doesn't contain id attribute") except: pass @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_with_get_exception(self, fetcher_get): fetcher_get.side_effect = Exception("get exception") try: self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.fail( "Can't get exception when fetcher.get throws an exception") except: pass @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_without_master_parent(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITHOUT_MASTER_PARENT_IN_DB # store original get_by_id original_get_by_id = self.scanner.inv.get_by_id original_set = self.scanner.inv.set # mock methods self.scanner.inv.get_by_id = MagicMock(return_value=[]) result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) # reset methods self.scanner.inv.get_by_id = original_get_by_id self.scanner.inv.set = original_set self.assertEqual( result, [], "Can't get [], when the master parent " + "doesn't exist in database") @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_with_master_parent(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_MASTER_PARENT_IN_DB # store original methods original_get_by_id = self.scanner.inv.get_by_id original_set = self.scanner.inv.set # mock methods self.scanner.inv.get_by_id = MagicMock(return_value=MASTER_PARENT) self.scanner.inv.set = MagicMock() self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertEqual(self.scanner.inv.set.call_count, 2, "Can't create additional folder") self.assertNotIn("master_parent_type", DB_RESULTS_WITH_MASTER_PARENT_IN_DB, "Can't delete the master_parent_type") self.assertNotIn("master_parent_id", DB_RESULTS_WITH_MASTER_PARENT_IN_DB, "Can't delete the master_parent_id") # reset methods self.scanner.inv.get_by_id = original_get_by_id self.scanner.inv.set = original_set @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_with_in_project(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_PROJECT # store original method original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id # mock method self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertIn("projects", DB_RESULTS_WITH_PROJECT[0], "Can't get the projects from DB result") self.assertNotIn(PROJECT_KEY, DB_RESULTS_WITH_PROJECT[0], "Can't delete the project key in the object") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_without_create_object(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITHOUT_CREATE_OBJECT original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertEqual(self.scanner.inv.set.call_count, 0, "Set the object when the create object is false") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_with_create_object(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertEqual(self.scanner.inv.set.call_count, 1, "Set the object when the create object is false") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_with_children_scanner(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id original_queue_for_scan = self.scanner.queue_for_scan self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.queue_for_scan = MagicMock() self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertEqual(self.scanner.queue_for_scan.call_count, 1, "Can't put children scanner in the queue") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id self.scanner.queue_for_scan = original_queue_for_scan @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type_without_children_scanner(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id original_queue_for_scan = self.scanner.queue_for_scan self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.queue_for_scan = MagicMock() self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENV_WITHOUT_CHILDREN_FETCHER, PARENT, ID_FIELD) self.assertEqual(self.scanner.queue_for_scan.call_count, 0, "Can't put children scanner in the queue") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id self.scanner.queue_for_scan = original_queue_for_scan @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") def test_scan_type(self, fetcher_get): fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT original_set = self.scanner.inv.set original_get_by_id = self.scanner.inv.get_by_id original_queue_for_scan = self.scanner.queue_for_scan self.scanner.inv.set = MagicMock() self.scanner.inv.get_by_id = MagicMock(return_value=PARENT) self.scanner.queue_for_scan = MagicMock() result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) self.assertNotEqual(result, [], "Can't get children form scan_type") self.scanner.inv.set = original_set self.scanner.inv.get_by_id = original_get_by_id self.scanner.queue_for_scan = original_queue_for_scan def test_scan_with_limit_to_child_type(self): original_scan_type = self.scanner.scan_type original_get_scanner = self.scanner.get_scanner self.scanner.scan_type = MagicMock(return_value=[]) self.scanner.get_scanner = MagicMock(return_value=TYPES_TO_FETCH) limit_to_child_type = TYPES_TO_FETCH[0]['type'] self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT, limit_to_child_type=limit_to_child_type) # only scan the limit child type self.scanner.scan_type.assert_called_with(TYPES_TO_FETCH[0], PARENT, ID_FIELD) self.scanner.scan_type = original_scan_type self.scanner.get_scanner = original_get_scanner def test_scan_with_limit_to_child_id(self): original_scan_type = self.scanner.scan_type original_get_scanner = self.scanner.get_scanner self.scanner.get_scanner = MagicMock(return_value=TYPES_TO_FETCH) limit_to_child_id = SCAN_TYPE_RESULTS[0][ID_FIELD] self.scanner.scan_type = MagicMock(return_value=SCAN_TYPE_RESULTS) children = self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT, id_field=ID_FIELD, limit_to_child_id=limit_to_child_id) # only get the limit child self.assertEqual(children, SCAN_TYPE_RESULTS[0]) self.scanner.scan_type = original_scan_type self.scanner.get_scanner = original_get_scanner def test_scan(self): original_scan_type = self.scanner.scan_type original_get_scanner = self.scanner.get_scanner self.scanner.get_scanner = MagicMock(return_values=TYPES_TO_FETCH) result = self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT) self.assertEqual(PARENT, result, "Can't get the original parent after the scan") self.scanner.get_scanner = original_get_scanner self.scanner.scan_type = original_scan_type def test_run_scan(self): original_scan = self.scanner.scan original_scan_from_queue = self.scanner.scan_from_queue self.scanner.scan = MagicMock() self.scanner.scan_from_queue = MagicMock() self.scanner.run_scan(SCANNER_TYPE_FOR_ENV, PARENT, ID_FIELD, LIMIT_TO_CHILD_ID, LIMIT_TO_CHILD_TYPE) self.scanner.scan.assert_called_with(SCANNER_TYPE_FOR_ENV, PARENT, ID_FIELD, LIMIT_TO_CHILD_ID, LIMIT_TO_CHILD_TYPE) self.scanner.scan_from_queue.assert_any_call() self.scanner.scan = original_scan self.scanner.scan_from_queue = original_scan_from_queue @patch("discover.scanner.Scanner.scan") def test_scan_from_queue(self, scan): scan.return_value = [] Scanner.scan_queue = SCAN_QUEUE self.scanner.scan_from_queue() self.assertEqual(self.scanner.scan.call_count, QUEUE_SIZE, "Can't scan all the objects in the queue")
def handle(self, env, notification): # check for network document. subnet = notification['payload']['subnet'] project_id = notification['_context_project_id'] project = notification['_context_project_name'] host_id = notification['publisher_id'].replace('network.', '', 1) subnet_id = subnet['id'] network_id = subnet['network_id'] network_document = self.inv.get_by_id(env, network_id) if not network_document: self.log.info( 'network document does not exist, aborting subnet update') return EventResult(result=False, retry=True) # update network document. subnets = network_document['subnets'] key = next(filter(lambda k: subnets[k]['id'] == subnet_id, subnets), None) if key: if subnet['enable_dhcp'] and subnets[key]['enable_dhcp'] is False: # scan DHCP namespace to add related document. # add dhcp vservice document. host = self.inv.get_by_id(env, host_id) port_handler = EventPortAdd() port_handler.add_dhcp_document(env, host, network_id, network_document['name']) # make sure that self.regions is not empty. if not ApiAccess.regions: fetcher = ApiFetchRegions() fetcher.set_env(env) fetcher.get(project_id) self.log.info("add port binding to DHCP server.") port_id = DbFetchPort(). \ get_id_by_field(network_id, """device_owner LIKE "%dhcp" """) port = EventSubnetAdd(). \ add_port_document(env, port_id, network_name=network_document['name'], project_name=project) if port: port_handler. \ add_vnic_document(env, host, network_id, network_name=network_document['name'], mac_address=port['mac_address']) # add link for vservice - vnic FindLinksForVserviceVnics().add_links( search={"id": "qdhcp-%s" % network_id}) scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() FindLinksForVserviceVnics(). \ add_links(search={"id": "qdhcp-%s" % network_id}) scanner = Scanner() scanner.set_env(env) scanner.scan_cliques() if subnet['enable_dhcp'] is False and subnets[key]['enable_dhcp']: # delete existed related DHCP documents. self.inv.delete("inventory", {'id': "qdhcp-%s" % subnet['network_id']}) self.log.info("delete DHCP document: qdhcp-%s" % subnet['network_id']) port = self.inv.find_items( { 'network_id': subnet['network_id'], 'device_owner': 'network:dhcp' }, get_single=True) if 'id' in port: EventPortDelete().delete_port(env, port['id']) self.log.info("delete port binding to DHCP server.") if subnet['name'] == subnets[key]['name']: subnets[key] = subnet else: del subnets[key] subnets[subnet['name']] = subnet self.inv.set(network_document) return EventResult(result=True, related_object=subnet['id'], display_context=network_id) else: self.log.info('subnet not in network, aborting subnet update') return EventResult(result=False, retry=False)