def object_create(self, obj_ids, obj_dict): obj_type = obj_ids['type'] obj_class = self._db_client_mgr.get_resource_class(obj_type) if not 'parent_type' in obj_dict: # parent is config-root parent_type = 'config-root' parent_imid = 'contrail:config-root:root' else: parent_type = obj_dict['parent_type'] parent_imid = obj_ids.get('parent_imid', None) # Parent Link Meta update = {} parent_cls = self._db_client_mgr.get_resource_class(parent_type) parent_link_meta = parent_cls.children_field_metas.get('%ss' % (obj_type)) if parent_link_meta: meta = Metadata(parent_link_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail') self._update_id_pair_meta(update, obj_ids['imid'], meta) self._publish_update(parent_imid, update) (ok, result) = self.object_set(obj_class, obj_ids['imid'], None, obj_dict) return (ok, result)
def object_create(self, obj_ids, obj_dict): """From resource ID, create the corresponding IF-MAP identity.""" obj_ifmap_id = obj_ids['imid'] obj_type = obj_ids['type'] obj_class = self._db_client_mgr.get_resource_class(obj_type) if 'parent_type' not in obj_dict: # parent is config-root parent_type = 'config-root' parent_ifmap_id = 'contrail:config-root:root' else: parent_type = obj_dict['parent_type'] parent_ifmap_id = obj_ids.get('parent_imid', None) # Parent Link Meta parent_cls = self._db_client_mgr.get_resource_class(parent_type) parent_link_meta = parent_cls.children_field_metas.get( '%ss' % (obj_type)) if parent_link_meta: metadata = Metadata(parent_link_meta, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail') VncIfmapServer.update(parent_ifmap_id, obj_ifmap_id, metadatas=[metadata]) return self._object_set(obj_class, obj_ifmap_id, obj_dict)
def _health_checker(self): while True: try: # do the healthcheck only if we are connected if self._conn_state == ConnectionStatus.DOWN: continue meta = Metadata('display-name', '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements='') request_str = self._build_request('healthcheck', 'self', [meta]) self._publish_to_ifmap_enqueue('update', request_str, do_trace=False) # Confirm the existence of the following default global entities in IFMAP. search_list = [ ('global-system-config', ['default-global-system-config']), ] for type, fq_name in search_list: if not entity_is_present(self._mapclient, type, fq_name): raise Exception("%s not found in IFMAP DB" % ':'.join(fq_name)) # If we had unpublished the IFMAP server to discovery server earlier # publish it back now since it is valid now. if not self._is_ifmap_up: self._get_api_server().publish_ifmap_to_discovery('up', '') self._is_ifmap_up = True ConnectionState.update( conn_type=ConnectionType.IFMAP, name='IfMap', status=ConnectionStatus.UP, message='', server_addrs=[ "%s:%s" % (self._ifmap_srv_ip, self._ifmap_srv_port) ]) except Exception as e: log_str = 'IFMAP Healthcheck failed: %s' % (str(e)) self.config_log(log_str, level=SandeshLevel.SYS_ERR) if self._is_ifmap_up: self._get_api_server().publish_ifmap_to_discovery( 'down', 'IFMAP DB - Invalid state') self._is_ifmap_up = False ConnectionState.update( conn_type=ConnectionType.IFMAP, name='IfMap', status=ConnectionStatus.DOWN, message='Invalid IFMAP DB State', server_addrs=[ "%s:%s" % (self._ifmap_srv_ip, self._ifmap_srv_port) ]) finally: gevent.sleep( self._get_api_server().get_ifmap_health_check_interval())
def __init__(self, db_client_mgr, ifmap_srv_ip, ifmap_srv_port, uname, passwd, ssl_options, ifmap_srv_loc=None): super(VncIfmapClient, self).__init__() # TODO username/passwd from right place self._CONTRAIL_XSD = "http://www.contrailsystems.com/vnc_cfg.xsd" self._IPERMS_NAME = "id-perms" self._IPERMS_FQ_NAME = "contrail:" + self._IPERMS_NAME self._SUBNETS_NAME = "contrail:subnets" self._IPAMS_NAME = "contrail:ipams" self._SG_RULE_NAME = "contrail:sg_rules" self._POLICY_ENTRY_NAME = "contrail:policy_entry" self._NAMESPACES = { 'env': "http://www.w3.org/2003/05/soap-envelope", 'ifmap': "http://www.trustedcomputinggroup.org/2010/IFMAP/2", 'meta': "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2", 'contrail': self._CONTRAIL_XSD } self._db_client_mgr = db_client_mgr # launch mapserver if ifmap_srv_loc: self._launch_mapserver(ifmap_srv_ip, ifmap_srv_port, ifmap_srv_loc) mapclient = client(("%s" % (ifmap_srv_ip), "%s" % (ifmap_srv_port)), uname, passwd, self._NAMESPACES, ssl_options) self._mapclient = mapclient connected = False while not connected: try: result = mapclient.call('newSession', NewSessionRequest()) connected = True except socket.error as e: time.sleep(3) mapclient.set_session_id(newSessionResult(result).get_session_id()) mapclient.set_publisher_id(newSessionResult(result).get_publisher_id()) # Initialize ifmap-id handler (alloc|convert|parse etc.) self._imid_handler = Imid() imid = self._imid_handler # Publish init config (TODO this should come from api-server init) # config-root buf = cStringIO.StringIO() perms = Provision.defaults.perms['config-root'] perms.exportChildren(buf, level=1, pretty_print=False) id_perms_xml = buf.getvalue() buf.close() meta = str(Metadata(self._IPERMS_NAME, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=id_perms_xml)) self._publish_id_self_meta("contrail:config-root:root", meta)
def _publish_config_root(self): # Remove all resident data result = ifmap_wipe(self._mapclient) if result is None: msg = "Cannot purge the IF-MAP server before publishing root graph" self.config_log(msg, level=SandeshLevel.SYS_WARN) # Build default config-root buf = cStringIO.StringIO() perms = Provision.defaults.perms perms.exportChildren(buf, level=1, pretty_print=False) id_perms_xml = buf.getvalue() buf.close() update = {} meta = Metadata(self._IPERMS_NAME, '', {'ifmap-cardinality': 'singleValue'}, ns_prefix='contrail', elements=id_perms_xml) self._update_id_self_meta(update, meta) self._publish_update("contrail:config-root:root", update)
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 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, '')