def initialize_all_server_resource_classes(server_instance): """Initialize map of all resource server classes. Initialize with the API server instance a class for all Contrail resource types with generated common resource class in vnc_api lib and the server resource class mixin which overloads common classes with all necessary hooks for CRUD API calls. These hooks will be empty if they the resource class does not defines its server class in that module. :param server_instance: `vnc_cfg_api_server.api_server.VncApiServer` instance :returns: map of server resource class with the resource type as key (in both formats ('-' and '_') if resource have multiple word in its name """ server_class_map = {} for object_type, resource_type in all_resource_type_tuples: common_name = object_type.title().replace('_', '') server_name = '%sServer' % common_name server_class = str_to_class(server_name, __name__) if not server_class: common_class = str_to_class(common_name, resource_common.__name__) # Create Placeholder classes derived from ResourceMixin, <Type> so # resource server class methods can be invoked in CRUD methods # without checking for None server_class = type(native_str(server_name), (ResourceMixin, common_class, object), {}) server_class.server = server_instance server_class_map[object_type] = server_class server_class_map[resource_type] = server_class return server_class_map
def initialize_all_server_resource_classes(server_instance): """Initialize map of all resource server classes. Initialize with the API server instance a class for all Contrail resource types with generated common resource class in vnc_api lib and the server resource class mixin which overloads common classes with all necessary hooks for CRUD API calls. These hooks will be empty if they the resource class does not defines its server class in that module. :param server_instance: `vnc_cfg_api_server.vnc_cfg_api_server.VncApiServer` instance :returns: map of server resource class with the resource type as key (in both formats ('-' and '_') if resource have multiple word in its name """ server_class_map = {} for object_type, resource_type in all_resource_type_tuples: common_name = object_type.title().replace('_', '') server_name = '%sServer' % common_name server_class = str_to_class(server_name, __name__) if not server_class: common_class = str_to_class(common_name, resource_common.__name__) # Create Placeholder classes derived from ResourceMixin, <Type> so # resource server class methods can be invoked in CRUD methods # without checking for None server_class = type( str(server_name), (ResourceMixin, common_class, object), {}) server_class.server = server_instance server_class_map[object_type] = server_class server_class_map[resource_type] = server_class return server_class_map
def get_object_class(res_type): cls_name = '%s' %(utils.CamelCase(res_type)) return utils.str_to_class(cls_name, __name__)
def get_object_class(obj_type): cls_name = '%s' %(utils.CamelCase(obj_type.replace('-', '_'))) return utils.str_to_class(cls_name, __name__)
def _object_set(self, obj_class, ifmap_id, obj_dict, existing_links=None): # Properties Metadata metadatas = [] for prop_field in obj_class.prop_fields: prop_value = obj_dict.get(prop_field) if prop_value is None: continue # construct object of xsd-type and get its xml repr # e.g. virtual_network_properties prop_field_types = obj_class.prop_field_types[prop_field] is_simple = not prop_field_types['is_complex'] prop_type = prop_field_types['xsd_type'] # e.g. virtual-network-properties meta_name = obj_class.prop_field_metas[prop_field] meta_long_name = 'contrail:%s' % meta_name meta_value = '' meta_elements = '' if prop_field in self.IFMAP_PUBLISH_SKIP_LIST: # Field not relevant, skip publishing to IfMap if not self.IFMAP_PUBLISH_SKIP_LIST[prop_field]: continue # Call the handler fn to generate the relevant fields. try: func = getattr(self, self.IFMAP_PUBLISH_SKIP_LIST[prop_field]) meta_elements = func(prop_field, prop_value) except AttributeError: log_str = ("%s is marked for partial publish to Ifmap but " "handler not defined" % prop_field) self._log(log_str, level=SandeshLevel.SYS_DEBUG) continue elif is_simple: meta_value = escape(str(prop_value)) else: # complex type prop_cls = str_to_class(prop_type, __name__) buf = StringIO() # perms might be inserted at server as obj. # obj construction diff from dict construction. if isinstance(prop_value, dict): prop_cls(**prop_value).exportChildren(buf, level=1, name_=meta_name, pretty_print=False) elif isinstance(prop_value, list): for elem in prop_value: if isinstance(elem, dict): prop_cls(**elem).exportChildren(buf, level=1, name_=meta_name, pretty_print=False) else: elem.exportChildren(buf, level=1, name_=meta_name, pretty_print=False) else: # object prop_value.exportChildren(buf, level=1, name_=meta_name, pretty_print=False) meta_elements = buf.getvalue() buf.close() meta = Metadata(meta_name, meta_value, {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=meta_elements) # If obj is new (existing metas is none) or # if obj does not have this meta (or) # or if the meta is different from what we have currently, # then update if (not existing_links or meta_long_name not in existing_links or ('meta' in existing_links[meta_long_name] and unicode(meta) != existing_links[meta_long_name]['meta'])): metadatas.append(meta) # end for all property types VncIfmapServer.update(ifmap_id, metadatas=metadatas) # References Metadata for ref_field in obj_class.ref_fields: refs = obj_dict.get(ref_field) if not refs: continue for ref in refs: ref_fq_name = ref['to'] ref_fld_types_list = list(obj_class.ref_field_types[ref_field]) ref_res_type = ref_fld_types_list[0] ref_link_type = ref_fld_types_list[1] ref_meta = obj_class.ref_field_metas[ref_field] ref_ifmap_id = get_ifmap_id_from_fq_name(ref_res_type, ref_fq_name) ref_data = ref.get('attr') if ref_data: buf = StringIO() attr_cls = str_to_class(ref_link_type, __name__) attr_cls(**ref_data).exportChildren(buf, level=1, name_=ref_meta, pretty_print=False) ref_link_xml = buf.getvalue() buf.close() else: ref_link_xml = '' metadata = Metadata(ref_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=ref_link_xml) VncIfmapServer.update(ifmap_id, ref_ifmap_id, [metadata]) # end for all ref types return (True, '')
def _load_init_data(self): """ Load init data for job playbooks. This function loads init data from a data file specified by the argument '--fabric_ansible_dir' to the database. The data file must be in JSON format and follow the format below "my payload": { "object_type": "tag" "objects": [ { "fq_name": [ "fabric=management_ip" ], "name": "fabric=management_ip", "tag_type_name": "fabric", "tag_value": "management_ip" } ] } """ try: json_data = self._load_json_data() if json_data is None: self._logger.error('Unable to load init data') return for item in json_data.get("data"): object_type = item.get("object_type") # Get the class name from object type cls_name = CamelCase(object_type) # Get the class object cls_ob = str_to_class(cls_name, resource_client.__name__) # saving the objects to the database for obj in item.get("objects"): instance_obj = cls_ob.from_dict(**obj) # create/update the object fq_name = instance_obj.get_fq_name() try: uuid = self._vnc_api.fq_name_to_id( object_type, fq_name) if object_type == "tag": continue instance_obj.set_uuid(uuid) # Update config json inside role-config object if object_type == 'role-config': role_config_obj = self._vnc_api.\ role_config_read(id=uuid) cur_config_json = json.loads( role_config_obj.get_role_config_config()) def_config_json = json.loads( instance_obj.get_role_config_config()) def_config_json.update(cur_config_json) instance_obj.set_role_config_config( json.dumps(def_config_json)) if object_type != 'telemetry-profile' and \ object_type != 'sflow-profile': self._vnc_api._object_update( object_type, instance_obj) except NoIdError: self._vnc_api._object_create(object_type, instance_obj) for item in json_data.get("refs"): from_type = item.get("from_type") from_fq_name = item.get("from_fq_name") from_uuid = self._vnc_api.fq_name_to_id( from_type, from_fq_name) to_type = item.get("to_type") to_fq_name = item.get("to_fq_name") to_uuid = self._vnc_api.fq_name_to_id(to_type, to_fq_name) self._vnc_api.ref_update(from_type, from_uuid, to_type, to_uuid, to_fq_name, 'ADD') except Exception as e: err_msg = 'error while loading init data: %s\n' % str(e) err_msg += detailed_traceback() self._logger.error(err_msg) # - fetch list of all the physical routers # - check physical and overlay role associated with each PR # - create ref between physical_role and physical_router object, # if PR is assigned with a specific physical role # - create ref between overlay_roles and physical_router object, # if PR is assigned with specific overlay roles obj_list = self._vnc_api._objects_list('physical-router') pr_list = obj_list.get('physical-routers') for pr in pr_list or []: try: pr_obj = self._vnc_api.\ physical_router_read(id=pr.get('uuid')) physical_role = pr_obj.get_physical_router_role() overlay_roles = pr_obj.get_routing_bridging_roles() if overlay_roles is not None: overlay_roles = overlay_roles.get_rb_roles() if physical_role: try: physical_role_uuid = self._vnc_api.\ fq_name_to_id('physical_role', ['default-global-system-config', physical_role]) if physical_role_uuid: self._vnc_api.ref_update('physical-router', pr.get('uuid'), 'physical-role', physical_role_uuid, None, 'ADD') except NoIdError: pass if overlay_roles: for overlay_role in overlay_roles or []: try: overlay_role_uuid = self._vnc_api.\ fq_name_to_id('overlay_role', ['default-global-system-config', overlay_role.lower()]) if overlay_role_uuid: self._vnc_api.ref_update( 'physical-router', pr.get('uuid'), 'overlay-role', overlay_role_uuid, None, 'ADD') except NoIdError: pass except NoIdError: pass # handle deleted job_templates as part of in-place cluster update to_be_del_jt_names = [ 'show_interfaces_template', 'show_config_interfaces_template', 'show_interfaces_by_names_template' ] for jt_name in to_be_del_jt_names: try: self._vnc_api.job_template_delete( fq_name=['default-global-system-config', jt_name]) except NoIdError: pass
def _load_init_data(self): """ Load init data for job playbooks. This function loads init data from a data file specified by the argument '--fabric_ansible_dir' to the database. The data file must be in JSON format and follow the format below "my payload": { "object_type": "tag" "objects": [ { "fq_name": [ "fabric=management_ip" ], "name": "fabric=management_ip", "tag_type_name": "fabric", "tag_value": "management_ip" } ] } """ try: json_data = self._load_json_data() if json_data is None: self._logger.error('Unable to load init data') return for item in json_data.get("data"): object_type = item.get("object_type") # Get the class name from object type cls_name = CamelCase(object_type) # Get the class object cls_ob = str_to_class(cls_name, resource_client.__name__) # saving the objects to the database for obj in item.get("objects"): instance_obj = cls_ob.from_dict(**obj) # create/update the object fq_name = instance_obj.get_fq_name() try: uuid_id = self._vnc_api.fq_name_to_id( object_type, fq_name) if object_type == "tag": continue instance_obj.set_uuid(uuid_id) # Update config json inside role-config object if object_type == 'role-config': role_config_obj = self._vnc_api.\ role_config_read(id=uuid_id) cur_config_json = json.loads( role_config_obj.get_role_config_config()) def_config_json = json.loads( instance_obj.get_role_config_config()) def_config_json.update(cur_config_json) instance_obj.set_role_config_config( json.dumps(def_config_json)) if object_type != 'telemetry-profile' and \ object_type != 'sflow-profile' and \ object_type != 'device-functional-group': self._vnc_api._object_update( object_type, instance_obj) except NoIdError: self._vnc_api._object_create(object_type, instance_obj) for item in json_data.get("refs"): from_type = item.get("from_type") from_fq_name = item.get("from_fq_name") from_uuid = self._vnc_api.fq_name_to_id( from_type, from_fq_name) to_type = item.get("to_type") to_fq_name = item.get("to_fq_name") to_uuid = self._vnc_api.fq_name_to_id(to_type, to_fq_name) self._vnc_api.ref_update(from_type, from_uuid, to_type, to_uuid, to_fq_name, 'ADD') except Exception as e: err_msg = 'error while loading init data: %s\n' % str(e) err_msg += detailed_traceback() self._logger.error(err_msg) # create VN and IPAM for IPV6 link-local addresses ipv6_link_local_nw = '_internal_vn_ipv6_link_local' self._create_ipv6_ll_ipam_and_vn(self._vnc_api, ipv6_link_local_nw) # - fetch list of all the physical routers # - check physical and overlay role associated with each PR # - create ref between physical_role and physical_router object, # if PR is assigned with a specific physical role # - create ref between overlay_roles and physical_router object, # if PR is assigned with specific overlay roles obj_list = self._vnc_api._objects_list('physical-router') pr_list = obj_list.get('physical-routers') for pr in pr_list or []: try: pr_obj = self._vnc_api.\ physical_router_read(id=pr.get('uuid')) physical_role = pr_obj.get_physical_router_role() overlay_roles = pr_obj.get_routing_bridging_roles() if overlay_roles is not None: overlay_roles = overlay_roles.get_rb_roles() if physical_role: try: physical_role_uuid = self._vnc_api.\ fq_name_to_id('physical_role', ['default-global-system-config', physical_role]) if physical_role_uuid: self._vnc_api.ref_update('physical-router', pr.get('uuid'), 'physical-role', physical_role_uuid, None, 'ADD') except NoIdError: pass if overlay_roles: for overlay_role in overlay_roles or []: try: overlay_role_uuid = self._vnc_api.\ fq_name_to_id('overlay_role', ['default-global-system-config', overlay_role.lower()]) if overlay_role_uuid: self._vnc_api.ref_update( 'physical-router', pr.get('uuid'), 'overlay-role', overlay_role_uuid, None, 'ADD') except NoIdError: pass except NoIdError: pass # handle replacing master-LR as <fab_name>-master-LR here # as part of in-place cluster update. Copy the master-LR # and also its associated vns and their annotations here master_lr_obj = None try: master_lr_obj = self._vnc_api.logical_router_read( fq_name=['default-domain', 'default-project', 'master-LR']) except NoIdError: try: master_lr_obj = self._vnc_api.logical_router_read( fq_name=['default-domain', 'admin', 'master-LR']) except NoIdError: pass if master_lr_obj: vmi_refs = master_lr_obj.get_virtual_machine_interface_refs() or [] # get existing pr refs pr_refs = master_lr_obj.get_physical_router_refs() or [] fabric_refs = master_lr_obj.get_fabric_refs() or [] perms2 = master_lr_obj.get_perms2() fab_fq_name = None try: # This has to happen before creating fab-master-LR as # otherwise it will fail creation # of fab-master-lr with annotations having master-lr uuid # Now delete master-LR object # this will delete lr annotations from fabric in # corresponding VNs if they exist self._vnc_api.logical_router_delete( id=master_lr_obj.get_uuid()) # try to obtain the fabric refs either by fabric ref if one # is available or from pr_refs if available if pr_refs and not fabric_refs: # this is assuming that even though there can be # multiple pr refs, a LR cannot have more than # one fabric refs. So a random pr chosen in the pr # refs list will have the same fabric name as the other # prs in the list pr_ref = pr_refs[-1] pr_obj = self._vnc_api.physical_router_read(id=pr_ref.get( 'uuid', self._vnc_api.fq_name_to_id(pr_ref.get('to')))) fabric_refs = pr_obj.get_fabric_refs() or [] if fabric_refs: fabric_ref = fabric_refs[-1] fab_fq_name = fabric_ref.get( 'to', self._vnc_api.id_to_fq_name(fabric_ref.get('uuid'))) # if fab_fq_name is not derivable or was not present, then # skip creating fab_name-master-LR as fabric information # is not available # if fab_fq_name is available, copy necessary refs from prev. # master LR, create new fab_name-master-LR and this will update # VN annotations accordingly. if fab_fq_name: def_project = self._vnc_api.project_read( ['default-domain', 'default-project']) fab_name = fab_fq_name[-1] lr_fq_name = [ 'default-domain', 'default-project', fab_name + '-master-LR' ] fab_master_lr_obj = LogicalRouter( name=lr_fq_name[-1], fq_name=lr_fq_name, logical_router_gateway_external=False, logical_router_type='vxlan-routing', parent_obj=def_project) perms2.set_global_access(PERMS_RWX) fab_master_lr_obj.set_perms2(perms2) fab_master_lr_obj.set_virtual_machine_interface_list( vmi_refs) fab_master_lr_obj.set_physical_router_list(pr_refs) fab_master_lr_obj.set_fabric_list(fabric_refs) self._vnc_api.logical_router_create(fab_master_lr_obj) except NoIdError: pass except Exception as exc: err_msg = "An exception occurred while attempting to " \ "create fabric master-LR: %s " % exc.message self._logger.warning(err_msg) # handle deleted job_templates as part of in-place cluster update to_be_del_jt_names = [ 'show_interfaces_template', 'show_config_interfaces_template', 'show_interfaces_by_names_template' ] for jt_name in to_be_del_jt_names: try: self._vnc_api.job_template_delete( fq_name=['default-global-system-config', jt_name]) except NoIdError: pass
def get_object_class(obj_type): cls_name = '%s' % (utils.CamelCase(obj_type.replace('-', '_'))) return utils.str_to_class(cls_name, __name__)
def object_set(self, obj_class, my_imid, existing_metas, obj_dict): update = {} # Properties Meta for prop_field in obj_class.prop_fields: field = obj_dict.get(prop_field) if field is None: continue # construct object of xsd-type and get its xml repr # e.g. virtual_network_properties prop_field_types = obj_class.prop_field_types[prop_field] is_simple = not prop_field_types['is_complex'] prop_type = prop_field_types['xsd_type'] # e.g. virtual-network-properties prop_meta = obj_class.prop_field_metas[prop_field] if prop_field in VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST: # Field not relevant, skip publishing to IfMap if not VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[prop_field]: continue # Call the handler fn to generate the relevant fields. if callable( VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[prop_field]): prop_xml = VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[ prop_field](prop_field, field) meta = Metadata(prop_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=prop_xml) else: log_str = '%s is marked for partial publish\ to Ifmap but handler not defined' % (prop_field) self.config_log(log_str, level=SandeshLevel.SYS_DEBUG) continue elif is_simple: norm_str = escape(str(field)) meta = Metadata(prop_meta, norm_str, {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail') else: # complex type prop_cls = str_to_class(prop_type, __name__) buf = cStringIO.StringIO() # perms might be inserted at server as obj. # obj construction diff from dict construction. if isinstance(field, dict): prop_cls(**field).exportChildren(buf, level=1, name_=prop_meta, pretty_print=False) elif isinstance(field, list): for elem in field: if isinstance(elem, dict): prop_cls(**elem).exportChildren(buf, level=1, name_=prop_meta, pretty_print=False) else: elem.exportChildren(buf, level=1, name_=prop_meta, pretty_print=False) else: # object field.exportChildren(buf, level=1, name_=prop_meta, pretty_print=False) prop_xml = buf.getvalue() buf.close() meta = Metadata(prop_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=prop_xml) # If obj is new (existing metas is none) or # if obj does not have this prop_meta (or) # or if the prop_meta is different from what we have currently, # then update if (not existing_metas or not prop_meta in existing_metas or ('' in existing_metas[prop_meta] and str(meta) != str(existing_metas[prop_meta]['']))): self._update_id_self_meta(update, meta) # end for all property types # References Meta for ref_field in obj_class.ref_fields: refs = obj_dict.get(ref_field) if not refs: continue for ref in refs: ref_fq_name = ref['to'] ref_fld_types_list = list(obj_class.ref_field_types[ref_field]) ref_res_type = ref_fld_types_list[0] ref_link_type = ref_fld_types_list[1] ref_meta = obj_class.ref_field_metas[ref_field] ref_imid = get_ifmap_id_from_fq_name(ref_res_type, ref_fq_name) ref_data = ref.get('attr') if ref_data: buf = cStringIO.StringIO() attr_cls = str_to_class(ref_link_type, __name__) attr_cls(**ref_data).exportChildren(buf, level=1, name_=ref_meta, pretty_print=False) ref_link_xml = buf.getvalue() buf.close() else: ref_link_xml = '' meta = Metadata(ref_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=ref_link_xml) self._update_id_pair_meta(update, ref_imid, meta) # end for all ref types self._publish_update(my_imid, update) return (True, '')
def _load_init_data(self): """ Load init data for job playbooks. This function loads init data from a data file specified by the argument '--fabric_ansible_dir' to the database. The data file must be in JSON format and follow the format below "my payload": { "object_type": "tag" "objects": [ { "fq_name": [ "fabric=management_ip" ], "name": "fabric=management_ip", "tag_type_name": "fabric", "tag_value": "management_ip" } ] } """ try: json_data = self._load_json_data() if json_data is None: self._logger.error('Unable to load init data') return for item in json_data.get("data"): object_type = item.get("object_type") # Get the class name from object type cls_name = CamelCase(object_type) # Get the class object cls_ob = str_to_class(cls_name, resource_client.__name__) # saving the objects to the database for obj in item.get("objects"): instance_obj = cls_ob.from_dict(**obj) # create/update the object fq_name = instance_obj.get_fq_name() try: uuid = self._vnc_api.fq_name_to_id( object_type, fq_name) if object_type == "tag": continue instance_obj.set_uuid(uuid) self._vnc_api._object_update(object_type, instance_obj) except NoIdError: self._vnc_api._object_create(object_type, instance_obj) for item in json_data.get("refs"): from_type = item.get("from_type") from_fq_name = item.get("from_fq_name") from_uuid = self._vnc_api.fq_name_to_id( from_type, from_fq_name) to_type = item.get("to_type") to_fq_name = item.get("to_fq_name") to_uuid = self._vnc_api.fq_name_to_id(to_type, to_fq_name) self._vnc_api.ref_update(from_type, from_uuid, to_type, to_uuid, to_fq_name, 'ADD') except Exception as e: err_msg = 'error while loading init data: %s\n' % str(e) err_msg += detailed_traceback() self._logger.error(err_msg)
def _load_init_data(self): """ This function loads init data from a data file specified by the argument '--fabric_ansible_dir' to the database. The data file must be in JSON format and follow the format below: { "data": [ { "object_type": "<vnc object type name>", "objects": [ { <vnc object payload> }, ... ] }, ... ] } Here is an example: { "data": [ { "object_type": "tag", "objects": [ { "fq_name": [ "fabric=management_ip" ], "name": "fabric=management_ip", "tag_type_name": "fabric", "tag_value": "management_ip" } ] } ] } """ try: json_data = self._load_json_data() if json_data is None: self._logger.error('Unable to load init data') return for item in json_data.get("data"): object_type = item.get("object_type") # Get the class name from object type cls_name = CamelCase(object_type) # Get the class object cls_ob = str_to_class(cls_name, resource_client.__name__) # saving the objects to the database for obj in item.get("objects"): instance_obj = cls_ob.from_dict(**obj) # create/update the object fq_name = instance_obj.get_fq_name() try: uuid = self._vnc_api.fq_name_to_id(object_type, fq_name) if object_type == "tag": continue instance_obj.set_uuid(uuid) self._vnc_api._object_update(object_type, instance_obj) except NoIdError: self._vnc_api._object_create(object_type, instance_obj) for item in json_data.get("refs"): from_type = item.get("from_type") from_fq_name = item.get("from_fq_name") from_uuid = self._vnc_api.fq_name_to_id(from_type, from_fq_name) to_type = item.get("to_type") to_fq_name = item.get("to_fq_name") to_uuid = self._vnc_api.fq_name_to_id(to_type, to_fq_name) self._vnc_api.ref_update(from_type, from_uuid, to_type, to_uuid, to_fq_name, 'ADD') except Exception as e: err_msg = 'error while loading init data: %s\n' % str(e) err_msg += detailed_traceback() self._logger.error(err_msg)
def object_set(self, obj_class, my_imid, existing_metas, obj_dict): update = {} # Properties Meta for prop_field in obj_class.prop_fields: field = obj_dict.get(prop_field) if field is None: continue # construct object of xsd-type and get its xml repr # e.g. virtual_network_properties prop_field_types = obj_class.prop_field_types[prop_field] is_simple = not prop_field_types['is_complex'] prop_type = prop_field_types['xsd_type'] # e.g. virtual-network-properties prop_meta = obj_class.prop_field_metas[prop_field] if prop_field in VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST: # Field not relevant, skip publishing to IfMap if not VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[prop_field]: continue # Call the handler fn to generate the relevant fields. if callable(VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[prop_field]): prop_xml = VncIfmapClient.IFMAP_PUBLISH_SKIP_LIST[prop_field]( prop_field, field) meta = Metadata(prop_meta, '', {'ifmap-cardinality':'singleValue'}, ns_prefix='contrail', elements=prop_xml) else: log_str = '%s is marked for partial publish\ to Ifmap but handler not defined' %( prop_field) self.config_log(log_str, level=SandeshLevel.SYS_DEBUG) continue elif is_simple: norm_str = escape(str(field)) meta = Metadata(prop_meta, norm_str, {'ifmap-cardinality':'singleValue'}, ns_prefix = 'contrail') else: # complex type prop_cls = str_to_class(prop_type, __name__) buf = cStringIO.StringIO() # perms might be inserted at server as obj. # obj construction diff from dict construction. if isinstance(field, dict): prop_cls(**field).exportChildren( buf, level=1, name_=prop_meta, pretty_print=False) elif isinstance(field, list): for elem in field: if isinstance(elem, dict): prop_cls(**elem).exportChildren( buf, level=1, name_=prop_meta, pretty_print=False) else: elem.exportChildren( buf, level=1, name_=prop_meta, pretty_print=False) else: # object field.exportChildren( buf, level=1, name_=prop_meta, pretty_print=False) prop_xml = buf.getvalue() buf.close() meta = Metadata(prop_meta, '', {'ifmap-cardinality':'singleValue'}, ns_prefix='contrail', elements=prop_xml) # If obj is new (existing metas is none) or # if obj does not have this prop_meta (or) # or if the prop_meta is different from what we have currently, # then update if (not existing_metas or not prop_meta in existing_metas or ('' in existing_metas[prop_meta] and str(meta) != str(existing_metas[prop_meta]['']))): self._update_id_self_meta(update, meta) # end for all property types # References Meta for ref_field in obj_class.ref_fields: refs = obj_dict.get(ref_field) if not refs: continue for ref in refs: ref_fq_name = ref['to'] ref_fld_types_list = list( obj_class.ref_field_types[ref_field]) ref_res_type = ref_fld_types_list[0] ref_link_type = ref_fld_types_list[1] ref_meta = obj_class.ref_field_metas[ref_field] ref_imid = get_ifmap_id_from_fq_name(ref_res_type, ref_fq_name) ref_data = ref.get('attr') if ref_data: buf = cStringIO.StringIO() attr_cls = str_to_class(ref_link_type, __name__) attr_cls(**ref_data).exportChildren( buf, level=1, name_=ref_meta, pretty_print=False) ref_link_xml = buf.getvalue() buf.close() else: ref_link_xml = '' meta = Metadata(ref_meta, '', {'ifmap-cardinality':'singleValue'}, ns_prefix = 'contrail', elements=ref_link_xml) self._update_id_pair_meta(update, ref_imid, meta) # end for all ref types self._publish_update(my_imid, update) return (True, '')
def _object_set(self, obj_class, ifmap_id, obj_dict, existing_links=None): # Properties Metadata metadatas = [] for prop_field in obj_class.prop_fields: prop_value = obj_dict.get(prop_field) if prop_value is None: continue # construct object of xsd-type and get its xml repr # e.g. virtual_network_properties prop_field_types = obj_class.prop_field_types[prop_field] is_simple = not prop_field_types["is_complex"] prop_type = prop_field_types["xsd_type"] # e.g. virtual-network-properties meta_name = obj_class.prop_field_metas[prop_field] meta_long_name = "contrail:%s" % meta_name meta_value = "" meta_elements = "" if prop_field in self.IFMAP_PUBLISH_SKIP_LIST: # Field not relevant, skip publishing to IfMap if not self.IFMAP_PUBLISH_SKIP_LIST[prop_field]: continue # Call the handler fn to generate the relevant fields. try: func = getattr(self, self.IFMAP_PUBLISH_SKIP_LIST[prop_field]) meta_elements = func(prop_field, prop_value) except AttributeError: log_str = "%s is marked for partial publish to Ifmap but " "handler not defined" % prop_field self._log(log_str, level=SandeshLevel.SYS_DEBUG) continue elif is_simple: meta_value = escape(str(prop_value)) else: # complex type prop_cls = str_to_class(prop_type, __name__) buf = StringIO() # perms might be inserted at server as obj. # obj construction diff from dict construction. if isinstance(prop_value, dict): prop_cls(**prop_value).exportChildren(buf, level=1, name_=meta_name, pretty_print=False) elif isinstance(prop_value, list): for elem in prop_value: if isinstance(elem, dict): prop_cls(**elem).exportChildren(buf, level=1, name_=meta_name, pretty_print=False) else: elem.exportChildren(buf, level=1, name_=meta_name, pretty_print=False) else: # object prop_value.exportChildren(buf, level=1, name_=meta_name, pretty_print=False) meta_elements = buf.getvalue() buf.close() meta = Metadata( meta_name, meta_value, {"ifmap-cardinality": "singleValue"}, ns_prefix="contrail", elements=meta_elements, ) # If obj is new (existing metas is none) or # if obj does not have this meta (or) # or if the meta is different from what we have currently, # then update if ( not existing_links or meta_long_name not in existing_links or ( "meta" in existing_links[meta_long_name] and unicode(meta) != existing_links[meta_long_name]["meta"] ) ): metadatas.append(meta) # end for all property types VncIfmapServer.update(ifmap_id, metadatas=metadatas) # References Metadata for ref_field in obj_class.ref_fields: refs = obj_dict.get(ref_field) if not refs: continue for ref in refs: ref_fq_name = ref["to"] ref_fld_types_list = list(obj_class.ref_field_types[ref_field]) ref_res_type = ref_fld_types_list[0] ref_link_type = ref_fld_types_list[1] ref_meta = obj_class.ref_field_metas[ref_field] ref_ifmap_id = get_ifmap_id_from_fq_name(ref_res_type, ref_fq_name) ref_data = ref.get("attr") if ref_data: buf = StringIO() attr_cls = str_to_class(ref_link_type, __name__) attr_cls(**ref_data).exportChildren(buf, level=1, name_=ref_meta, pretty_print=False) ref_link_xml = buf.getvalue() buf.close() else: ref_link_xml = "" metadata = Metadata( ref_meta, "", {"ifmap-cardinality": "singleValue"}, ns_prefix="contrail", elements=ref_link_xml ) VncIfmapServer.update(ifmap_id, ref_ifmap_id, [metadata]) # end for all ref types return (True, "")