class ApicAssignment(resource.ResourceBase): """Track the APIC to aim-aid mapping""" identity_attributes = t.identity( ('apic_host', t.string(128))) other_attributes = t.other( ('aim_aid_id', t.string(64))) db_attributes = t.db( ('last_update_timestamp', t.string())) def __init__(self, **kwargs): super(ApicAssignment, self).__init__({'aim_aid_id': ''}, **kwargs) def is_available(self, context): current = context.store.current_timestamp # When the store doesn't support time stamp, the APIC can never # be considered available. if current is None: return False result = current - self.last_update_timestamp >= datetime.timedelta( seconds=cfg.CONF.aim.apic_available_time) if result: LOG.info("APIC %s is available. Last update time was %s" % (self.apic_host, self.last_update_timestamp)) return True else: LOG.debug("APIC %s is not available. Last update time was %s" % (self.apic_host, self.last_update_timestamp)) return False
class L3OutInterface(AciResourceBase): """Resource representing a logical interface. Identity attributes: name of ACI tenant, name of L3Out, name of node profile, name of interface profile, interface_path. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('node_profile_name', t.name), ('interface_profile_name', t.name), ('interface_path', t.string())) other_attributes = t.other( ('primary_addr_a', t.ip_cidr), ('secondary_addr_a_list', t.list_of_ip_cidr_obj), ('primary_addr_b', t.ip_cidr), ('secondary_addr_b_list', t.list_of_ip_cidr_obj), ('encap', t.string()), ('mode', t.enum(*t.spmodes.values())), ('host', t.string()), ('type', t.enum("ext-svi")), ('monitored', t.bool)) _aci_mo_name = 'l3extRsPathL3OutAtt' _tree_parent = L3OutInterfaceProfile def __init__(self, **kwargs): super(L3OutInterface, self).__init__( {'primary_addr_a': '', 'secondary_addr_a_list': [], 'primary_addr_b': '', 'secondary_addr_b_list': [], 'encap': '', 'type': 'ext-svi', 'mode': 'regular', 'monitored': False, 'host': ''}, **kwargs)
class ExternalSubnet(AciResourceBase): """Resource representing an external subnet. Identity attributes: name of ACI tenant, name of L3Out, name of external network, network CIDR of the subnet. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('external_network_name', t.name), ('cidr', t.ip_cidr)) other_attributes = t.other( ('display_name', t.name), ('aggregate', t.string()), ('scope', t.string()), ('monitored', t.bool)) _aci_mo_name = 'l3extSubnet' _tree_parent = ExternalNetwork def __init__(self, **kwargs): super(ExternalSubnet, self).__init__({'monitored': False, 'aggregate': "", 'scope': "import-security"}, **kwargs)
class VmmInjectedHost(AciResourceBase): """Resource representing a VMM injected host in ACI. Identity attributes: VMM domain type, VMM domain name, controller name and host name. """ identity_attributes = t.identity( ('domain_type', t.name), ('domain_name', t.name), ('controller_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('host_name', t.string()), ('kernel_version', t.string()), ('os', t.string())) _aci_mo_name = 'vmmInjectedHost' _tree_parent = VMMController def __init__(self, **kwargs): super(VmmInjectedHost, self).__init__({'host_name': '', 'kernel_version': '', 'os': ''}, **kwargs)
class L3OutInterfaceBgpPeerP(AciResourceBase): """Resource representing a bgp peer prefix. Identity attributes: name of ACI tenant, name of L3Out, name of node profile, name of interface profile, interface_path, bgp peer prefix. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('node_profile_name', t.name), ('interface_profile_name', t.name), ('interface_path', t.string()), ('addr', t.ip_cidr)) other_attributes = t.other( ('asn', t.string()), ('monitored', t.bool)) _aci_mo_name = 'bgpPeerP' _tree_parent = L3OutInterface def __init__(self, **kwargs): asn = kwargs.get('asn') if asn and (int(asn) < 0 or int(asn) > 4294967295): raise exc.AciResourceValueError(klass=type(self).__name__, value=asn, attr='asn') super(L3OutInterfaceBgpPeerP, self).__init__( {'asn': "0", 'monitored': False}, **kwargs)
class DeviceClusterInterfaceContext(resource.AciResourceBase): """Resource representing a device-cluster logical interface context. """ identity_attributes = t.identity( ('tenant_name', t.name), ('contract_name', t.name), ('service_graph_name', t.name), ('node_name', t.name), ('connector_name', t.name)) other_attributes = t.other( ('display_name', t.name), ('device_cluster_interface_dn', t.string()), ('service_redirect_policy_dn', t.string()), ('bridge_domain_dn', t.string()), ('monitored', t.bool)) _aci_mo_name = 'vnsLIfCtx' _tree_parent = DeviceClusterContext def __init__(self, **kwargs): super(DeviceClusterInterfaceContext, self).__init__( { 'display_name': '', 'device_cluster_interface_dn': '', 'service_redirect_policy_dn': '', 'bridge_domain_dn': '', 'monitored': False }, **kwargs)
class DeviceCluster(resource.AciResourceBase): """Represents a device-cluster and associated ACI objects. """ identity_attributes = t.identity(('tenant_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('device_type', t.enum("PHYSICAL", "VIRTUAL")), ('service_type', t.enum("ADC", "FW", "OTHERS", "IDSIPS", "COPY")), ('context_aware', t.enum("single-Context", "multi-Context")), ('managed', t.bool), ('physical_domain_name', t.name), ('encap', t.string(24)), ('devices', t.list_of_dicts( ('name', t.name), ('path', t.string(512)))), ('monitored', t.bool)) _aci_mo_name = 'vnsLDevVip' _tree_parent = resource.Tenant def __init__(self, **kwargs): super(DeviceCluster, self).__init__( { 'display_name': '', 'device_type': 'PHYSICAL', 'service_type': 'OTHERS', 'context_aware': 'single-Context', 'managed': True, 'physical_domain_name': '', 'encap': '', 'devices': [], 'monitored': False }, **kwargs)
class OpflexDevice(resource.AciResourceBase): """Information about Opflex device reported by ACI. Read-only.""" root = 'topology' identity_attributes = t.identity( ('pod_id', t.id), ('node_id', t.id), ('bridge_interface', t.id), ('dev_id', t.id)) other_attributes = t.other( ('host_name', t.string(128)), ('ip', t.string(64)), ('fabric_path_dn', t.string()), ('domain_name', t.string(64)), ('controller_name', t.string(64))) _aci_mo_name = 'opflexODev' _tree_parent = resource.Pod def __init__(self, **kwargs): super(OpflexDevice, self).__init__({'host_name': '', 'ip': '', 'fabric_path_dn': '', 'domain_name': '', 'controller_name': ''}, **kwargs) # force read-only object to be in monitored tree self.monitored = True
class L3OutStaticRoute(AciResourceBase): """Resource representing a static route. Identity attributes: name of ACI tenant, name of L3Out, name of node profile, node_path of the node, cidr of the static route. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('node_profile_name', t.name), ('node_path', t.string()), ('cidr', t.ip_cidr)) other_attributes = t.other( ('next_hop_list', t.list_of_next_hop), ('preference', t.string()), ('display_name', t.name), ('monitored', t.bool)) _aci_mo_name = 'ipRouteP' _tree_parent = L3OutNode def __init__(self, **kwargs): super(L3OutStaticRoute, self).__init__( {'next_hop_list': [], 'preference': '1', 'monitored': False}, **kwargs)
class TypeTreeBase(object): identity_attributes = t.identity(('root_rn', t.string(64))) other_attributes = t.other(('root_full_hash', t.string(256)), ('tree', t.string())) db_attributes = t.db() def __init__(self, **kwargs): super(TypeTreeBase, self).__init__({}, **kwargs)
class AciFault(resource.ResourceBase, OperationalResource): """Fault information reported by ACI.""" LC_UNKNOWN = 0x0 LC_SOAKING = 0x1 LC_RETAINING = 0x10 LC_RAISED = 0x2 LC_SOAKING_CLEARING = 0x4 LC_RAISED_CLEARING = 0x8 SEV_CLEARED = 'cleared' SEV_INFO = 'info' SEV_WARNING = 'warning' SEV_MINOR = 'minor' SEV_MAJOR = 'major' SEV_CRITICAL = 'critical' _aci_mo_name = 'faultInst' identity_attributes = t.identity(('fault_code', t.string()), ('external_identifier', t.string())) other_attributes = t.other(('severity', t.enum(SEV_CLEARED, SEV_CRITICAL, SEV_INFO, SEV_WARNING, SEV_MAJOR, SEV_MINOR)), ('status_id', t.id), ('cause', t.string()), ('description', t.string(255))) db_attributes = t.db(('last_update_timestamp', t.string())) def __eq__(self, other): try: return self.identity == other.identity except AttributeError: return False def __init__(self, **kwargs): super(AciFault, self).__init__( { 'severity': self.SEV_INFO, 'lifecycle_status': self.LC_UNKNOWN, 'cause': '', 'description': "" }, **kwargs) def is_error(self): return self.severity in [self.SEV_MAJOR, self.SEV_CRITICAL] @property def dn(self): return self.external_identifier @property def root(self): mos_and_types = utils.decompose_dn(self._aci_mo_name, self.dn) if mos_and_types: # Faults associated with unrecognized MOs will not decompose mo = apic_client.ManagedObjectClass(mos_and_types[0][0]) return (mo.rn(mos_and_types[0][1]) if mo.rn_param_count else mo.rn())
class Configuration(ResourceBase): identity_attributes = t.identity( ('key', t.string(52)), ('host', t.string(52)), ('group', t.string(52))) other_attributes = t.other(('value', t.string(512))) db_attributes = t.db(('version', t.string(36))) def __init__(self, **kwargs): super(Configuration, self).__init__({}, **kwargs)
class HostLinkNetworkLabel(resource.ResourceBase): """A network label to host link""" identity_attributes = t.identity(('host_name', t.string(128)), ('network_label', t.string(64)), ('interface_name', t.string(32))) other_attributes = t.other() def __init__(self, **kwargs): super(HostLinkNetworkLabel, self).__init__({}, **kwargs)
class HostDomainMappingV2(resource.ResourceBase): """host to VMM and phys-dom mapping, version 2""" identity_attributes = t.identity( ('host_name', t.string(128)), ('domain_name', t.string(64)), ('domain_type', t.enum('PhysDom', 'OpenStack', 'Kubernetes', 'VMware'))) other_attributes = t.other() def __init__(self, **kwargs): super(HostDomainMappingV2, self).__init__({}, **kwargs)
class HostDomainMapping(resource.ResourceBase): """host to VMM and phys-dom mapping""" identity_attributes = t.identity( ('host_name', t.string(128))) other_attributes = t.other( ('vmm_domain_name', t.string(64)), ('physical_domain_name', t.string(64))) def __init__(self, **kwargs): super(HostDomainMapping, self).__init__({'vmm_domain_name': '', 'physical_domain_name': ''}, **kwargs)
class SecurityGroupRule(AciResourceBase): """Resource representing a SG subject's rule in ACI. Identity attributes: name of ACI tenant, name of security group, name of subject and name of rule """ identity_attributes = t.identity( ('tenant_name', t.name), ('security_group_name', t.name), ('security_group_subject_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('direction', t.enum("", "ingress", "egress")), ('ethertype', t.enum("", "undefined", "ipv4", "ipv6")), ('remote_ips', t.list_of_strings), ('ip_protocol', t.string()), ('from_port', t.port), ('to_port', t.port), ('conn_track', t.enum('normal', 'reflexive')), ('monitored', t.bool)) _aci_mo_name = 'hostprotRule' _tree_parent = SecurityGroupSubject def __init__(self, **kwargs): super(SecurityGroupRule, self).__init__( {'direction': 'ingress', 'ethertype': "undefined", 'remote_ips': [], 'ip_protocol': self.UNSPECIFIED, 'from_port': self.UNSPECIFIED, 'to_port': self.UNSPECIFIED, 'conn_track': 'reflexive', 'monitored': False}, **kwargs)
class Tree(api_res.ResourceBase): identity_attributes = t.identity(('root_rn', t.string(64))) other_attributes = t.other(('needs_reset', t.bool)) db_attributes = t.db() def __init__(self, **kwargs): super(Tree, self).__init__({}, **kwargs)
class VmmInjectedContGroup(AciResourceBase): """Resource representing a VMM injected container group in ACI. Identity attributes: VMM domain type, VMM domain name, controller name, namespace name and group name. """ identity_attributes = t.identity( ('domain_type', t.name), ('domain_name', t.name), ('controller_name', t.name), ('namespace_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('host_name', t.name), ('compute_node_name', t.name), ('replica_set_name', t.name)) db_attributes = t.db(('guid', t.string())) _aci_mo_name = 'vmmInjectedContGrp' _tree_parent = VmmInjectedNamespace def __init__(self, **kwargs): super(VmmInjectedContGroup, self).__init__({'host_name': '', 'compute_node_name': '', 'replica_set_name': '', 'guid': ''}, **kwargs)
class ExternalNetwork(AciResourceBase): """Resource representing an external network instance profile. External network is a group of external subnets that have the same security behavior. Identity attributes: name of ACI tenant, name of L3Out, name of external network. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('nat_epg_dn', t.string()), ('provided_contract_names', t.list_of_names), ('consumed_contract_names', t.list_of_names), ('monitored', t.bool)) _aci_mo_name = 'l3extInstP' _tree_parent = L3Outside def __init__(self, **kwargs): super(ExternalNetwork, self).__init__( {'nat_epg_dn': '', 'provided_contract_names': [], 'consumed_contract_names': [], 'monitored': False}, **kwargs)
class ActionLog(api_res.ResourceBase): CREATE = 'create' DELETE = 'delete' RESET = 'reset' identity_attributes = t.identity(('uuid', t.string(64))) other_attributes = t.other( ('action', t.enum(CREATE, DELETE, RESET)), ('object_type', t.string(50)), ('object_dict', t.string()), ('root_rn', t.string(64)), ) db_attributes = t.db(('timestamp', t.string()), ('id', t.integer)) def __init__(self, **kwargs): super(ActionLog, self).__init__({'uuid': utils.generate_uuid()}, **kwargs)
class L3OutInterfaceBgpPeerP(AciResourceBase): """Resource representing a bgp peer prefix. Identity attributes: name of ACI tenant, name of L3Out, name of node profile, name of interface profile, interface_path, bgp peer prefix. """ identity_attributes = t.identity( ('tenant_name', t.name), ('l3out_name', t.name), ('node_profile_name', t.name), ('interface_profile_name', t.name), ('interface_path', t.string()), ('addr', t.ip_cidr)) other_attributes = t.other( ('asn', t.string()), ('monitored', t.bool)) _aci_mo_name = 'bgpPeerP' _tree_parent = L3OutInterface def __init__(self, **kwargs): super(L3OutInterfaceBgpPeerP, self).__init__( {'asn': "0", 'monitored': False}, **kwargs)
class FilterEntry(AciResourceBase): """Resource representing a classifier entry of a filter in ACI. Identity attributes: name of ACI tenant, name of filter and name of entry. Values for classification fields may be integers as per standards (e.g. ip_protocol = 6 for TCP, 17 for UDP), or special strings listed below. UNSPECIFIED may be used to indicate that a particular field should be ignored. Field | Special string values -------------------------------------------------------------------------- arp_opcode | req, reply ether_type | trill, arp, mpls_ucast, mac_security, fcoe, ip ip_protocol | icmp, igmp, tcp, egp, igp, udp, icmpv6, eigrp, ospfigp icmpv4_type | echo-rep, dst-unreach, src-quench, echo, time-exceeded icmpv6_type | dst-unreach, time-exceeded, echo-req, echo-rep, | nbr-solicit, nbr-advert, redirect source_from_port, | ftpData, smtp, dns, http, pop3, https, rtsp source_to_port, | dest_from_port, | dest_to_port | tcp_flags | est, syn, ack, fin, rst """ identity_attributes = t.identity(('tenant_name', t.name), ('filter_name', t.name), ('name', t.name)) other_attributes = t.other( ('display_name', t.name), ('arp_opcode', t.string()), ('ether_type', t.string()), ('ip_protocol', t.string()), ('icmpv4_type', t.string()), ('icmpv6_type', t.string()), ('source_from_port', t.port), ('source_to_port', t.port), ('dest_from_port', t.port), ('dest_to_port', t.port), ('tcp_flags', t.string()), ('stateful', t.bool), ('fragment_only', t.bool), ('monitored', t.bool)) _aci_mo_name = 'vzEntry' _tree_parent = Filter def __init__(self, **kwargs): super(FilterEntry, self).__init__( { 'arp_opcode': self.UNSPECIFIED, 'ether_type': self.UNSPECIFIED, 'ip_protocol': self.UNSPECIFIED, 'icmpv4_type': self.UNSPECIFIED, 'icmpv6_type': self.UNSPECIFIED, 'source_from_port': self.UNSPECIFIED, 'source_to_port': self.UNSPECIFIED, 'dest_from_port': self.UNSPECIFIED, 'dest_to_port': self.UNSPECIFIED, 'tcp_flags': self.UNSPECIFIED, 'stateful': False, 'fragment_only': False, 'monitored': False }, **kwargs)
class Agent(ResourceBase): """Resource representing an AIM Agent""" identity_attributes = t.identity(('id', t.id)) other_attributes = t.other( ('agent_type', t.string(255)), ('host', t.string(255)), ('binary_file', t.string(255)), ('admin_state_up', t.bool), ('description', t.string(255)), ('hash_trees', t.list_of_ids), ('version', t.string())) # Attrbutes completely managed by the DB (eg. timestamps) db_attributes = t.db(('heartbeat_timestamp', t.string())) def __init__(self, **kwargs): super(Agent, self).__init__({'admin_state_up': True, 'id': utils.generate_uuid()}, **kwargs) def __eq__(self, other): return self.id == other.id # An object is hashable if it has a hash value which never changes during # its lifetime (it needs a __hash__() method), and can be compared to # other objects (it needs an __eq__() or __cmp__() method). # Hashable objects which compare equal must have the same hash value. # # If you define __eq__() , the default __hash__() (namely, hashing the # address of the object in memory) goes away. # So for each class defining __eq__() we must also # define __hash__() even though parent class has __hash__(). def __hash__(self): return super(Agent, self).__hash__() def is_down(self, context): current = context.store.current_timestamp # When the store doesn't support timestamps the agent can never # be considered down. if current is None: return False result = current - self.heartbeat_timestamp >= datetime.timedelta( seconds=cfg.CONF.aim.agent_down_time) if result: LOG.warn("Agent %s is down. Last heartbeat was %s" % (self.id, self.heartbeat_timestamp)) else: LOG.debug("Agent %s is alive, its last heartbeat was %s" % (self.id, self.heartbeat_timestamp)) return result def down_time(self, context): if self.is_down(context): current = context.store.current_timestamp return (current - self.heartbeat_timestamp).seconds
class VMMDomain(AciResourceBase): """Resource representing a VMM domain. Identity attributes: VMM type (eg. Openstack) and name """ identity_attributes = t.identity( ('type', t.enum("VMWare", "OpenStack", "Kubernetes")), ('name', t.name)) other_attributes = t.other( ('monitored', t.bool), ('display_name', t.name), ('enforcement_pref', t.enum('sw', 'hw', 'unknown')), ('mode', t.enum('default', 'n1kv', 'unknown', 'ovs', 'k8s')), ('mcast_address', t.string()), ('encap_mode', t.enum('unknown', 'vlan', 'vxlan')), ('pref_encap_mode', t.enum('unspecified', 'vlan', 'vxlan')), ('vlan_pool_name', t.name), ('vlan_pool_type', t.enum('static', 'dynamic')), ('mcast_addr_pool_name', t.name)) _aci_mo_name = 'vmmDomP' _tree_parent = VMMPolicy def __init__(self, **kwargs): defaults = { 'monitored': False, 'enforcement_pref': 'hw', 'mode': 'default', 'mcast_address': '0.0.0.0', 'encap_mode': 'unknown', 'pref_encap_mode': 'unspecified', 'vlan_pool_name': '', 'vlan_pool_type': 'dynamic', 'mcast_addr_pool_name': '' } vmm_type = kwargs.get('type') if vmm_type == 'Kubernetes': defaults['enforcement_pref'] = 'sw' defaults['mode'] = 'k8s' elif vmm_type == 'OpenStack': defaults['enforcement_pref'] = 'sw' defaults['mode'] = 'ovs' if kwargs.get('encap_mode') and kwargs['encap_mode'] != 'unknown': defaults['pref_encap_mode'] = kwargs['encap_mode'] super(VMMDomain, self).__init__(defaults, **kwargs)
class Tenant(AciRoot): """Resource representing a Tenant in ACI. Identity attribute is RN for ACI tenant. """ identity_attributes = t.identity(('name', t.name)) other_attributes = t.other(('display_name', t.name), ('monitored', t.bool), ('descr', t.string())) _aci_mo_name = 'fvTenant' _tree_parent = None def __init__(self, **kwargs): super(Tenant, self).__init__({ 'monitored': False, 'descr': '' }, **kwargs)
class ConcreteDeviceInterface(resource.AciResourceBase): """Resource representing interface of concrete device in device cluster. """ identity_attributes = t.identity(('tenant_name', t.name), ('device_cluster_name', t.name), ('device_name', t.name), ('name', t.name)) other_attributes = t.other(('display_name', t.name), ('path', t.string()), ('monitored', t.bool)) _aci_mo_name = 'vnsCIf' _tree_parent = ConcreteDevice def __init__(self, **kwargs): super(ConcreteDeviceInterface, self).__init__( { 'display_name': '', 'path': '', 'monitored': False }, **kwargs)
class VmmInjectedDeployment(AciResourceBase): """Resource representing a VMM injected deployment in ACI. Identity attributes: VMM domain type, VMM domain name, controller name, namespace name and deployment name. """ identity_attributes = t.identity( ('domain_type', t.name), ('domain_name', t.name), ('controller_name', t.name), ('namespace_name', t.name), ('name', t.name)) other_attributes = t.other(('display_name', t.name), ('replicas', t.integer)) db_attributes = t.db(('guid', t.string())) _aci_mo_name = 'vmmInjectedDepl' _tree_parent = VmmInjectedNamespace def __init__(self, **kwargs): super(VmmInjectedDeployment, self).__init__({ 'replicas': 0, 'guid': '' }, **kwargs)
class ServiceRedirectPolicy(resource.AciResourceBase): """Resource representing a service-redirect policy. """ identity_attributes = t.identity(('tenant_name', t.name), ('name', t.name)) other_attributes = t.other(('display_name', t.name), ('destinations', t.list_of_dicts(('ip', t.string()), ('mac', t.mac_address))), ('monitored', t.bool)) _aci_mo_name = 'vnsSvcRedirectPol' _tree_parent = resource.Tenant def __init__(self, **kwargs): super(ServiceRedirectPolicy, self).__init__( { 'display_name': '', 'destinations': [], 'monitored': False }, **kwargs)
class L3Outside(AciResourceBase): """Resource representing an L3 Outside. Identity attributes: name of ACI tenant, name of L3Out. """ identity_attributes = t.identity(('tenant_name', t.name), ('name', t.name)) other_attributes = t.other(('display_name', t.name), ('vrf_name', t.name), ('l3_domain_dn', t.string()), ('bgp_enable', t.bool), ('monitored', t.bool)) _aci_mo_name = 'l3extOut' _tree_parent = Tenant def __init__(self, **kwargs): super(L3Outside, self).__init__( { 'vrf_name': '', 'l3_domain_dn': '', 'bgp_enable': False, 'monitored': False }, **kwargs)
class HostLink(resource.ResourceBase): """Switch-port connection information for a host node.""" identity_attributes = t.identity(('host_name', t.string(36)), ('interface_name', t.string(36))) other_attributes = t.other( ('interface_mac', t.mac_address), ('switch_id', t.string()), ('module', t.string()), ('port', t.string()), ('path', t.string()), ('pod_id', t.string()), ('from_config', t.bool)) def __init__(self, **kwargs): super(HostLink, self).__init__( { 'interface_mac': '', 'switch_id': '', 'module': '', 'port': '', 'path': '', 'pod_id': '1', 'from_config': False }, **kwargs)