def test_interface_ordering_ios(self): INTERFACES = [ 'GigabitEthernet0/1', 'GigabitEthernet0/2', 'GigabitEthernet0/10', 'TenGigabitEthernet0/20', 'TenGigabitEthernet0/21', 'GigabitEthernet1/1', 'GigabitEthernet1/2', 'GigabitEthernet1/10', 'TenGigabitEthernet1/20', 'TenGigabitEthernet1/21', 'FastEthernet1', 'FastEthernet2', 'FastEthernet10', ] for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self.assertListEqual( list( Interface.objects.filter(device=self.device).values_list( 'name', flat=True)), INTERFACES)
def get_neighbors(self, switch): # dump LLDP neighbors resp = { "cnos": self.get_neighbors_cnos, "enos": self.get_neighbors_enos }[self.mode]() # parse response # example: [(my_port, remote_interface, remote_port),] for my_port, remote_port, remote_interface in resp: existing = Interface.objects.filter( device=switch, name=my_port, ) if existing: me = existing[0] else: me = Interface(device=switch, name=my_port) me.type = INTERFACE_TYPE_SWITCH_PORT me.save() # (me, them) pair. Do they exist? if InterfaceConnection.objects.filter( Q(interface_a=remote_interface, interface_b=me) | Q(interface_a=me, interface_b=remote_interface)): # nothing to do return else: InterfaceConnection(interface_a=me, interface_b=remote_interface).save()
def get_neighbors_enos(self): """Dump `lldp remote-device` table. Example output: ``` LLDP Remote Devices Information Legend(possible values in DMAC column) : NB - Nearest Bridge - 01-80-C2-00-00-0E NnTB - Nearest non-TPMR Bridge - 01-80-C2-00-00-03 NCB - Nearest Customer Bridge - 01-80-C2-00-00-00 Total number of current entries: 2 LocalPort | Index | Remote Chassis ID | Remote Port | Remote System Name | DMAC ----------|-------|---------------------------|----------------------|-------------------------------|--------- 2 | 2 | a4 8c db 34 d9 00 | MGT | | NB XGE4 | 1 | a4 8c db 34 d7 00 | 48 | LCTC-R2U37-SW | NB ``` Returns: tuple: (myport, remote_port, remote_interface) """ tmp = self._dump_info("show lldp remote-device", "LocalPort") records = [] # [(myport, remote_interface, remote_port),] entries = filter(lambda x: "|" in x, tmp.split("\n"))[2:] for e in entries: tmp = map(lambda x: x.strip(), e.split("|")) remote_port = self._cleanse_port(tmp[3]) if not remote_port: continue my_port = self._cleanse_port(tmp[0]) if not my_port: continue # remote device remote_switch_name = tmp[4].lstrip("\x00").strip() existing_devices = Device.objects.filter(name=remote_switch_name) if not existing_devices: # we haven't seen this device yet, # wait for next scan continue remote_device = existing_devices[0] # remote interface existing_interfaces = Interface.objects.filter( name=remote_port, device=remote_device) if existing_interfaces: remote_interface = existing_interfaces[0] else: remote_interface = Interface(name=remote_port, device=remote_device) remote_interface.mac_address = self._cleanse_mac(tmp[2]) remote_interface.save() records.append((my_port, remote_port, remote_interface)) return records
def run(self, data): vm = VirtualMachine( name=data["vm_name"], role=data["role"], status=data["status"], cluster=data["cluster"], platform=data["platform"], vcpus=data["vcpus"], memory=data["memory"], disk=data["disk"], comments=data["comments"], tenant=data.get("tenant"), ) vm.save() interface = Interface( name=data["interface_name"], type=InterfaceTypeChoices.TYPE_VIRTUAL, mac_address=data["mac_address"], virtual_machine=vm, ) interface.save() def add_addr(addr, expect_family): if not addr: return if addr.version != expect_family: raise RuntimeError("Wrong family for %r" % a) try: a = IPAddress.objects.get( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Assigned" except ObjectDoesNotExist: a = IPAddress( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Created" a.status = IPAddressStatusChoices.STATUS_ACTIVE a.dns_name = data["dns_name"] if a.interface: raise RuntimeError("Address %s is already assigned" % addr) a.interface = interface a.tenant = data.get("tenant") a.save() self.log_info("%s IP address %s %s" % (result, a.address, a.vrf or "")) setattr(vm, "primary_ip%d" % a.family, a) add_addr(data["primary_ip4"], 4) add_addr(data["primary_ip6"], 6) vm.save() self.log_success("Created VM %s" % vm.name)
def get_port_info(self, switch): port_info = { "cnos": self.get_port_info_cnos, "enos": self.get_port_info_enos }[self.mode]() for (port_id, is_trunk, native_vlan, allowed_vlans) in port_info: existing = Interface.objects.filter( device=switch, name=port_id, ) if existing: me = existing[0] else: me = Interface(device=switch, name=port_id) me.type = INTERFACE_TYPE_SWITCH_PORT me.is_trunk = is_trunk me.mode = IFACE_MODE_TAGGED # native vlan try: int(native_vlan) except: print "error:", port_id, native_vlan, allowed_vlans vlan, created = VLAN.objects.get_or_create(vid=int(native_vlan)) me.untagged_vlan = vlan # allowed vlan list me.allowed_vlans = ",".join(allowed_vlans) me.save()
def test_interface_ordering_junos(self): INTERFACES = [ 'xe-0/0/0', 'xe-0/0/1', 'xe-0/0/2', 'xe-0/0/3', 'xe-0/1/0', 'xe-0/1/1', 'xe-0/1/2', 'xe-0/1/3', 'xe-1/0/0', 'xe-1/0/1', 'xe-1/0/2', 'xe-1/0/3', 'xe-1/1/0', 'xe-1/1/1', 'xe-1/1/2', 'xe-1/1/3', 'xe-2/0/0.1', 'xe-2/0/0.2', 'xe-2/0/0.10', 'xe-2/0/0.11', 'xe-2/0/0.100', 'xe-3/0/0:1', 'xe-3/0/0:2', 'xe-3/0/0:10', 'xe-3/0/0:11', 'xe-3/0/0:100', 'xe-10/1/0', 'xe-10/1/1', 'xe-10/1/2', 'xe-10/1/3', 'ae1', 'ae2', 'ae10.1', 'ae10.10', 'irb.1', 'irb.2', 'irb.10', 'irb.100', 'lo0', ] for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self.assertListEqual( list( Interface.objects.filter(device=self.device).values_list( 'name', flat=True)), INTERFACES)
def test_interface_ordering_junos(self): INTERFACES = ( 'xe-0/0/0', 'xe-0/0/1', 'xe-0/0/2', 'xe-0/0/3', 'xe-0/1/0', 'xe-0/1/1', 'xe-0/1/2', 'xe-0/1/3', 'xe-1/0/0', 'xe-1/0/1', 'xe-1/0/2', 'xe-1/0/3', 'xe-1/1/0', 'xe-1/1/1', 'xe-1/1/2', 'xe-1/1/3', 'xe-2/0/0.1', 'xe-2/0/0.2', 'xe-2/0/0.10', 'xe-2/0/0.11', 'xe-2/0/0.100', 'xe-3/0/0:1', 'xe-3/0/0:2', 'xe-3/0/0:10', 'xe-3/0/0:11', 'xe-3/0/0:100', 'xe-10/1/0', 'xe-10/1/1', 'xe-10/1/2', 'xe-10/1/3', 'ae1', 'ae2', 'ae10.1', 'ae10.10', 'irb.1', 'irb.2', 'irb.10', 'irb.100', 'lo0', ) for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self._compare_names(Interface.objects.filter(device=self.device), INTERFACES)
def test_interface_ordering_numeric(self): INTERFACES = [ '0', '0.0', '0.1', '0.2', '0.10', '0.100', '0:1', '0:1.0', '0:1.1', '0:1.2', '0:1.10', '0:2', '0:2.0', '0:2.1', '0:2.2', '0:2.10', '1', '1.0', '1.1', '1.2', '1.10', '1.100', '1:1', '1:1.0', '1:1.1', '1:1.2', '1:1.10', '1:2', '1:2.0', '1:2.1', '1:2.2', '1:2.10', ] for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self.assertListEqual( list( Interface.objects.filter(device=self.device).values_list( 'name', flat=True)), INTERFACES)
def test_interface_ordering_linux(self): INTERFACES = ( 'eth0', 'eth0.1', 'eth0.2', 'eth0.10', 'eth0.100', 'eth1', 'eth1.1', 'eth1.2', 'eth1.100', 'lo0', ) for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self._compare_names(Interface.objects.filter(device=self.device), INTERFACES)
def setUpTestData(cls): cluster_types = ( ClusterType(name='Cluster Type 1', slug='cluster-type-1'), ClusterType(name='Cluster Type 2', slug='cluster-type-2'), ClusterType(name='Cluster Type 3', slug='cluster-type-3'), ) ClusterType.objects.bulk_create(cluster_types) clusters = ( Cluster(name='Cluster 1', type=cluster_types[0]), Cluster(name='Cluster 2', type=cluster_types[1]), Cluster(name='Cluster 3', type=cluster_types[2]), ) Cluster.objects.bulk_create(clusters) vms = ( VirtualMachine(name='Virtual Machine 1', cluster=clusters[0]), VirtualMachine(name='Virtual Machine 2', cluster=clusters[1]), VirtualMachine(name='Virtual Machine 3', cluster=clusters[2]), ) VirtualMachine.objects.bulk_create(vms) interfaces = ( Interface(virtual_machine=vms[0], name='Interface 1', enabled=True, mtu=100, mac_address='00-00-00-00-00-01'), Interface(virtual_machine=vms[1], name='Interface 2', enabled=True, mtu=200, mac_address='00-00-00-00-00-02'), Interface(virtual_machine=vms[2], name='Interface 3', enabled=False, mtu=300, mac_address='00-00-00-00-00-03'), ) Interface.objects.bulk_create(interfaces)
def test_interface_ordering_linux(self): INTERFACES = [ 'eth0', 'eth0.1', 'eth0.2', 'eth0.10', 'eth0.100', 'eth1', 'eth1.1', 'eth1.2', 'eth1.100', 'lo0', ] for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self.assertListEqual( list( Interface.objects.filter(device=self.device).values_list( 'name', flat=True)), INTERFACES)
def test_interface_ordering_ios(self): INTERFACES = ( 'GigabitEthernet0/1', 'GigabitEthernet0/2', 'GigabitEthernet0/10', 'TenGigabitEthernet0/20', 'TenGigabitEthernet0/21', 'GigabitEthernet1/1', 'GigabitEthernet1/2', 'GigabitEthernet1/10', 'TenGigabitEthernet1/20', 'TenGigabitEthernet1/21', 'FastEthernet1', 'FastEthernet2', 'FastEthernet10', ) for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self._compare_names(Interface.objects.filter(device=self.device), INTERFACES)
def run(self, data): """Create a 'mgmt' interface, and, if requested, allocate an appropriate IP address.""" device = data['device'] try: mgmt = device.interfaces.get(name='mgmt') self.log_info("mgmt already exists for device {}".format( device.name)) except ObjectDoesNotExist: # create interface of name mgmt, is_mgmt flag set of type 1G Ethernet mgmt = Interface(name="mgmt", mgmt_only=True, device=device, type=IFACE_TYPE_1GE_FIXED) mgmt.save() if data['add_ip']: return self._add_ip_to_interface(device, mgmt) else: message = "Created mgmt on device {}".format(device.name) self.log_success(message) return message
def test_interface_ordering_numeric(self): INTERFACES = ( '0', '0.1', '0.2', '0.10', '0.100', '0:1', '0:1.1', '0:1.2', '0:1.10', '0:2', '0:2.1', '0:2.2', '0:2.10', '1', '1.1', '1.2', '1.10', '1.100', '1:1', '1:1.1', '1:1.2', '1:1.10', '1:2', '1:2.1', '1:2.2', '1:2.10', ) for name in INTERFACES: iface = Interface(device=self.device, name=name) iface.save() self._compare_names(Interface.objects.filter(device=self.device), INTERFACES)
def get_mac_address(self, switch): # read MAC address table from switch mac_table = { "cnos": self.get_mac_address_cnos, "enos": self.get_mac_address_enos }[self.mode]() # parse MAC table if not mac_table: print "mac table query has failed. abort." return for mac, vlan_id, switch_port_name, state, is_openflow in mac_table: # mac can be formatted as "00:af" or "000.ed5" # we normalize them all into "00:af:a0:98" mac = self._cleanse_mac(mac) # vlan vlan, created = VLAN.objects.get_or_create(vid=vlan_id) # create Interface and link to switch switch_port_name = self._cleanse_port(switch_port_name) # Note: there are two interfaces we are to create: # 1. an switch port: device=switch, name = port number # 2. an interface on the other end of a switch traffic. Standing # from POV of a switch, we don't know which device it belongs to. # create switch port as Interface existing = Interface.objects.filter(device=switch, name=switch_port_name) if existing: m = existing[0] m.type = INTERFACE_TYPE_SWITCH_PORT else: m = Interface(device=switch, name=switch_port_name, type=INTERFACE_TYPE_SWITCH_PORT) m.enabled = True m.mode = DEVICE_STATUS_ACTIVE m.state = state m.save() m.tagged_vlans.add(vlan) # Create Interface on other side of traffic. # Note: we don't know the interface type. existing = InterfaceMacTraffic.objects.filter(interface=m, mac_address=mac) if not existing: InterfaceMacTraffic(interface=m, mac_address=mac).save()
def setUpTestData(cls): vrfs = ( VRF(name='VRF 1', rd='65000:100'), VRF(name='VRF 2', rd='65000:200'), VRF(name='VRF 3', rd='65000:300'), ) VRF.objects.bulk_create(vrfs) site = Site.objects.create(name='Site 1', slug='site-1') manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( Device(device_type=device_type, name='Device 1', site=site, device_role=device_role), Device(device_type=device_type, name='Device 2', site=site, device_role=device_role), Device(device_type=device_type, name='Device 3', site=site, device_role=device_role), ) Device.objects.bulk_create(devices) clustertype = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1') cluster = Cluster.objects.create(type=clustertype, name='Cluster 1') virtual_machines = ( VirtualMachine(name='Virtual Machine 1', cluster=cluster), VirtualMachine(name='Virtual Machine 2', cluster=cluster), VirtualMachine(name='Virtual Machine 3', cluster=cluster), ) VirtualMachine.objects.bulk_create(virtual_machines) interfaces = ( Interface(device=devices[0], name='Interface 1'), Interface(device=devices[1], name='Interface 2'), Interface(device=devices[2], name='Interface 3'), Interface(virtual_machine=virtual_machines[0], name='Interface 1'), Interface(virtual_machine=virtual_machines[1], name='Interface 2'), Interface(virtual_machine=virtual_machines[2], name='Interface 3'), ) Interface.objects.bulk_create(interfaces) ipaddresses = ( IPAddress(family=4, address='10.0.0.1/24', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), IPAddress(family=4, address='10.0.0.2/24', vrf=vrfs[0], interface=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), IPAddress(family=4, address='10.0.0.3/24', vrf=vrfs[1], interface=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), IPAddress(family=4, address='10.0.0.4/24', vrf=vrfs[2], interface=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), IPAddress(family=4, address='10.0.0.1/25', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), IPAddress(family=6, address='2001:db8::1/64', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), IPAddress(family=6, address='2001:db8::2/64', vrf=vrfs[0], interface=interfaces[3], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), IPAddress(family=6, address='2001:db8::3/64', vrf=vrfs[1], interface=interfaces[4], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), IPAddress(family=6, address='2001:db8::4/64', vrf=vrfs[2], interface=interfaces[5], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), IPAddress(family=6, address='2001:db8::1/65', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), ) IPAddress.objects.bulk_create(ipaddresses)
def setUpTestData(cls): device = create_test_device('test-device') interfaces = [ Interface(device=device, name=f'radio{i}', type=InterfaceTypeChoices.TYPE_80211AC, rf_channel=WirelessChannelChoices.CHANNEL_5G_32, rf_channel_frequency=5160, rf_channel_width=20) for i in range(12) ] Interface.objects.bulk_create(interfaces) wireless_links = ( WirelessLink(ssid='LINK1', interface_a=interfaces[0], interface_b=interfaces[1]), WirelessLink(ssid='LINK2', interface_a=interfaces[2], interface_b=interfaces[3]), WirelessLink(ssid='LINK3', interface_a=interfaces[4], interface_b=interfaces[5]), ) WirelessLink.objects.bulk_create(wireless_links) cls.create_data = [ { 'interface_a': interfaces[6].pk, 'interface_b': interfaces[7].pk, 'ssid': 'LINK4', }, { 'interface_a': interfaces[8].pk, 'interface_b': interfaces[9].pk, 'ssid': 'LINK5', }, { 'interface_a': interfaces[10].pk, 'interface_b': interfaces[11].pk, 'ssid': 'LINK6', }, ]
def get_system_info(self, switch): # dump switch system info mac, serial, part_no, mtm = { "cnos": self.get_system_info_cnos, "enos": self.get_system_info_enos }[self.mode]() # update switch: # 1. serial # 2. switch device's device type part number switch.serial = serial switch.save() switch.device_type.part_number = part_no switch.device_type.save() # From mac we create/update Interface existings = Interface.objects.filter(mac_address=mac) if existings: if existings.filter(device=switch): pass else: existings.update(device=switch) interface = existings[0] else: existing_mgmt = Interface.objects.filter(device=switch, name="mgmt0") if existing_mgmt: interface = existing_mgmt[0] else: interface = Interface( name="mgmt0", # used on CNOS switch at least. device=switch) interface.device = switch interface.mac_address = mac interface.type = INTERFACE_TYPE_MANAGEMENT interface.save() # link interface to secret & ip switch.primary_ip.interface = interface switch.primary_ip.save() ip, secret = switch.management_access secret.interface = interface
def setUpTestData(cls): device = create_test_device('test-device') interfaces = [ Interface(device=device, name=f'radio{i}', type=InterfaceTypeChoices.TYPE_80211AC, rf_channel=WirelessChannelChoices.CHANNEL_5G_32, rf_channel_frequency=5160, rf_channel_width=20) for i in range(12) ] Interface.objects.bulk_create(interfaces) WirelessLink(interface_a=interfaces[0], interface_b=interfaces[1], ssid='LINK1').save() WirelessLink(interface_a=interfaces[2], interface_b=interfaces[3], ssid='LINK2').save() WirelessLink(interface_a=interfaces[4], interface_b=interfaces[5], ssid='LINK3').save() tags = create_tags('Alpha', 'Bravo', 'Charlie') cls.form_data = { 'interface_a': interfaces[6].pk, 'interface_b': interfaces[7].pk, 'status': LinkStatusChoices.STATUS_PLANNED, 'tags': [t.pk for t in tags], } cls.csv_data = ( "interface_a,interface_b,status", f"{interfaces[6].pk},{interfaces[7].pk},connected", f"{interfaces[8].pk},{interfaces[9].pk},connected", f"{interfaces[10].pk},{interfaces[11].pk},connected", ) cls.bulk_edit_data = { 'status': LinkStatusChoices.STATUS_PLANNED, }
def dump_port_mac(self, switch): port_table = { "cnos": self.dump_port_mac_cnos, "enos": self.dump_port_mac_enos }[self.mode]() for port_number, mac, enabled in port_table: existing = Interface.objects.filter(device=switch, name=port_number) if existing: i = existing[0] else: i = Interface( device=switch, name=port_number, ) i.mac_address = mac i.type = INTERFACE_TYPE_SWITCH_PORT i.enabled = enabled i.save()
def setUp(self): self.client = Client() site = Site(name='Site 1', slug='site-1') site.save() manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1') manufacturer.save() devicetype = DeviceType(model='Device Type 1', manufacturer=manufacturer) devicetype.save() devicerole = DeviceRole(name='Device Role 1', slug='device-role-1') devicerole.save() device1 = Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole) device1.save() device2 = Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole) device2.save() iface1 = Interface(device=device1, name='Interface 1', form_factor=IFACE_FF_1GE_FIXED) iface1.save() iface2 = Interface(device=device1, name='Interface 2', form_factor=IFACE_FF_1GE_FIXED) iface2.save() iface3 = Interface(device=device1, name='Interface 3', form_factor=IFACE_FF_1GE_FIXED) iface3.save() iface4 = Interface(device=device2, name='Interface 1', form_factor=IFACE_FF_1GE_FIXED) iface4.save() iface5 = Interface(device=device2, name='Interface 2', form_factor=IFACE_FF_1GE_FIXED) iface5.save() iface6 = Interface(device=device2, name='Interface 3', form_factor=IFACE_FF_1GE_FIXED) iface6.save() Cable(termination_a=iface1, termination_b=iface4, type=CABLE_TYPE_CAT6).save() Cable(termination_a=iface2, termination_b=iface5, type=CABLE_TYPE_CAT6).save() Cable(termination_a=iface3, termination_b=iface6, type=CABLE_TYPE_CAT6).save()
def server_bmc_get(device_id): """To group all `get_` calls. It turned out that BMC only allows **1** SSH session at a time. The consequetive SSH call will return an error ``` X11 forwarding request failed on channel 0 Connection to 10.240.41.254 closed. ``` Args: device_id: host server id. This device should have a property `bmc_access` which has BMC (ip, secret). We are **ASSUMING** that a device has ONE BMC. """ server = Device.objects.get(id=device_id) the_bmc = server.bmc_controllers[0] ip, secret = server.bmc_access print "reading server %s BMC name" % ip cli = BmcByCli(ip, secret.name, secret.password) if not cli.connect(): print "Access to BMC %s has failed. abort." % ip the_bmc.status = DEVICE_STATUS_OFFLINE server.save() the_bmc.save() return else: the_bmc.status = DEVICE_STATUS_ACTIVE # server name # Example output: # # ``` # SystemName: brain4-3 # ContactPerson: # Location: # FullPostalAddress: # RoomID: # RackID: # LowestU: 0 # HeightU: 2 # ``` # # This is the name by BMC, not FQDN or hostname that OS represents. name = filter(lambda x: "SystemName" in x, cli.get_name().split("\n")) name = re.search("SystemName:(?P<name>.+)", name[0]).group("name").strip() if not server.name: server.name = name the_bmc.name = "%s BMC" % name # eth0 mac # Example output: # # ``` # -b : 08:94:ef:48:13:3d # ``` mac = cli.get_eth0_mac() mac = re.search("b\s+:(?P<mac>.*)", mac).group("mac").strip().upper() existings = Interface.objects.filter(mac_address=mac) if existings: i = existings[0] else: i = Interface(device=server) i.device = the_bmc i.name = "eth0" i.type = INTERFACE_TYPE_MANAGEMENT i.mgmt_only = True i.mac_address = mac i.save() # link Interface to its primary IP the_bmc.primary_ip4.interface = i the_bmc.primary_ip4.save() # vpd sys # To get serial number, uuid of this device. # # Example output: # ``` # Machine Type-Model Serial Number UUID # -------------- --------- ---- # 8871AC1 J11PGTT 60CD7A22827E11E79D09089 # ``` tmp = re.split("-+", cli.get_vpd_sys()) sys_info = re.split("\s+", tmp[-1].strip())[:3] the_bmc.serial = "" the_bmc.asset_tag = "" the_bmc.save() server.serial = sys_info[1] if server.asset_tag != sys_info[2]: if Device.objects.filter(asset_tag=sys_info[2]): # wow we have someone who already owned this tag! # Create a random uuid one. server.asset_tag = "Generated %s" % str(uuid.uuid4()) else: server.asset_tag = sys_info[2] server.save() server.device_type.part_number = sys_info[0] server.device_type.save() # get server's power state power = filter(lambda x: "power" in x, cli.get_name().split("\n")) for p in power: state = re.search("power\s(?P<state>.+)", power).group("state").strip() if state == "off": server.status = DEVICE_STATUS_POWERED_OFF elif state == "on": # Note: server BMC indicates `power on`, but OS may still # be in off state. pass server.save() # dump raid controllers inside server for c in cli.get_storage_controllers(): # manufacturer m, whatever = Manufacturer.objects.get_or_create( name=c["manufacturer"].strip(), slug=c["manufacturer"].lower().strip()) # device type model = c["model"] existing = DeviceType.objects.filter(slug=slugify(model)) if existing: dt = existing[0] else: dt, whatever = DeviceType.objects.get_or_create( manufacturer=m, model=model, slug=slugify(model), part_number=c["part_id"].strip(), u_height=0, # TODO: hardcoded special value! is_network_device=False, subdevice_role=SUBDEVICE_ROLE_CHILD) # items asset_tag = c["asset_tag"].strip() serial = c["serial"].strip() if not asset_tag: existing = InventoryItem.objects.filter(asset_tag=asset_tag) else: existing = InventoryItem.objects.filter(serial=serial) if existing: item = existing[0] else: # inventory item item = InventoryItem( device=server, manufacturer=m, discovered=True, asset_tag=c["asset_tag"].strip(), ) item.device_type = dt item.name = c["target"] item.part_id = c["part_id"].strip() item.serial = c["serial"].strip() item.description = convert_to_html_table(c["description"], ":") item.save() # dump disks inside server for c in cli.get_storage_drives(): # manufacturer m, whatever = Manufacturer.objects.get_or_create( name=c["manufacturer"].strip(), slug=c["manufacturer"].lower().strip()) # device type model = "/".join( filter(lambda x: x, [c["name"], c["disk_type"], c["media_type"]])) existing = DeviceType.objects.filter(slug=slugify(model)) if existing: dt = existing[0] else: dt, whatever = DeviceType.objects.get_or_create( manufacturer=m, model=model, slug=slugify(model), part_number=c["part_id"].strip(), u_height=0, # TODO: hardcoded special value! is_network_device=False, subdevice_role=SUBDEVICE_ROLE_CHILD) # inventory item item, whatever = InventoryItem.objects.get_or_create( device=server, manufacturer=m, device_type=dt, discovered=True, name=c["target"], part_id=c["part_id"].strip(), serial=c["serial"].strip(), ) item.description = convert_to_html_table(c["description"], ":") item.save() # dump fw tmp = cli.get_firmware_status() tmp = re.sub("-", "", tmp) item, whatever = InventoryItem.objects.get_or_create( device=server, name="firmware", discovered=True, ) item.description = convert_to_html_table(tmp) item.save()
def host_get_mac_consumer(host_id, is_virtual): if not is_virtual: host = Device.objects.get(id=host_id) else: host = VirtualMachine.objects.get(id=host_id) ip, secret = host.management_access resp = HostByCli(ip, secret.name, secret.password).get_mac() # Sample output: # # 8: ens4f1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT qlen 1000 # link/ether 90:e2:ba:e3:bc:d5 brd ff:ff:ff:ff:ff:ff # 9: ens5f0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT qlen 1000 # link/ether 90:e2:ba:e3:ba:80 brd ff:ff:ff:ff:ff:ff # # We are to parse this to extract interface name and mac address if not resp: host.status = DEVICE_STATUS_OFFLINE host.save() return else: host.status = DEVICE_STATUS_ACTIVE host.save() for (name, mac, ip) in resp: # There are 3 scenarios interface may have been generated: # # 1. MAC could have been seen by switch. In this case, we know the MAC # but doesn't know its name or host. So matching the MAC is the only option. # ASSUMPTION: MAC is unique of the entire inventory. # 2. a repeated scan of either switch host. In this case, we should # have had either a full match (name,mac,host) or None. # # Since (device,name) is unique, we have to check # interface carefully before creating a new one. # handle case #2, we have either seen a full match or none. aa = Interface.objects.filter(device=host, name=name, mac_address=mac) if aa: interface = aa[0] else: # search by (device,name) bb = Interface.objects.filter(device=host, name=name) if bb: bb.update(mac_address=mac) else: # search by (device,mac) cc = Interface.objects.filter(device=host, mac_address=mac) if cc: cc.update(name=name) else: interface = Interface(device=host, name=name, mac_address=mac) interface.save() # create IP # Note that IP can be duplicate, eg. 192.168.x.x is a private # address, thus can be available in multiple host. So we only # create new IPAddress if all existing one of this address has # already an Interface associated w/ it. if ip: # TODO: we have to iterate all IP because # manual input may have used wrong **mask*. for e in IPAddress.objects.all(): if ip == str(e.address.ip): if e.primary_ip4_for_set.all(): # if it's tied to a device for d in e.primary_ip4_for_set.all(): if d == host: e.address = ip e.save() existing_ip = IPAddress.objects.filter(address=ip, interface=interface) if existing_ip: my_ip = existing_ip[0] else: # we have create this IP, but has not associated it w/ anyone existing_ip = IPAddress.objects.filter(address=ip, interface__isnull=True) if existing_ip: my_ip = existing_ip[0] my_ip.interface = interface my_ip.save() else: my_ip = IPAddress(address=IPNetwork(ip), interface=interface) my_ip.save()
def setUpTestData(cls): manufacturers = ( Manufacturer(name='Manufacturer 1', slug='manufacturer-1'), Manufacturer(name='Manufacturer 2', slug='manufacturer-2'), Manufacturer(name='Manufacturer 3', slug='manufacturer-3'), ) Manufacturer.objects.bulk_create(manufacturers) device_types = ( DeviceType(manufacturer=manufacturers[0], model='Model 1', slug='model-1', is_full_depth=True), DeviceType(manufacturer=manufacturers[1], model='Model 2', slug='model-2', is_full_depth=True), DeviceType(manufacturer=manufacturers[2], model='Model 3', slug='model-3', is_full_depth=False), ) DeviceType.objects.bulk_create(device_types) device_roles = ( DeviceRole(name='Device Role 1', slug='device-role-1'), DeviceRole(name='Device Role 2', slug='device-role-2'), DeviceRole(name='Device Role 3', slug='device-role-3'), ) DeviceRole.objects.bulk_create(device_roles) platforms = ( Platform(name='Platform 1', slug='platform-1'), Platform(name='Platform 2', slug='platform-2'), Platform(name='Platform 3', slug='platform-3'), ) Platform.objects.bulk_create(platforms) regions = ( Region(name='Region 1', slug='region-1'), Region(name='Region 2', slug='region-2'), Region(name='Region 3', slug='region-3'), ) for region in regions: region.save() sites = ( Site(name='Site 1', slug='abc-site-1', region=regions[0], asn=65001), Site(name='Site 2', slug='def-site-2', region=regions[1], asn=65101), Site(name='Site 3', slug='ghi-site-3', region=regions[2], asn=65201), ) Site.objects.bulk_create(sites) rir = RIR.objects.create(name='RFC 6996', is_private=True) asns = [ ASN(asn=65001, rir=rir), ASN(asn=65101, rir=rir), ASN(asn=65201, rir=rir) ] ASN.objects.bulk_create(asns) asns[0].sites.add(sites[0]) asns[1].sites.add(sites[1]) asns[2].sites.add(sites[2]) racks = ( Rack(name='Rack 1', site=sites[0]), Rack(name='Rack 2', site=sites[1]), Rack(name='Rack 3', site=sites[2]), ) Rack.objects.bulk_create(racks) devices = ( Device(name='Device 1', device_type=device_types[0], device_role=device_roles[0], platform=platforms[0], serial='ABC', asset_tag='1001', site=sites[0], rack=racks[0], position=1, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_ACTIVE, local_context_data={"foo": 123}), Device(name='Device 2', device_type=device_types[1], device_role=device_roles[1], platform=platforms[1], serial='DEF', asset_tag='1002', site=sites[1], rack=racks[1], position=2, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_STAGED), Device(name='Device 3', device_type=device_types[2], device_role=device_roles[2], platform=platforms[2], serial='GHI', asset_tag='1003', site=sites[2], rack=racks[2], position=3, face=DeviceFaceChoices.FACE_REAR, status=DeviceStatusChoices.STATUS_FAILED), ) Device.objects.bulk_create(devices) interfaces = ( Interface(device=devices[0], name='Interface 1', mac_address='00-00-00-00-00-01'), Interface(device=devices[0], name='Interface 2', mac_address='aa-00-00-00-00-01'), Interface(device=devices[1], name='Interface 3', mac_address='00-00-00-00-00-02'), Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'), Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'), Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03'), ) Interface.objects.bulk_create(interfaces)
def sync_interfaces(device, interfaces): """ Syncing interfaces :param device: object NetBox Device :param interfaces: list of lists interfaces: interface['NAME'] - Name of interface interface['MAC'] - Mac-Address interface['IP'] - List of IP-address interface['MTU'] - MTU interface['DESCR'] - Description of interfaces interface['TYPE'] - Physical type of interface (Default 1G-cooper - cannot get from linux) interface['STATE'] - UP|DOWN :return: status: bool, message: string """ # Updated interface counter count = 0 # Init interfaces filter iface_filter = device.cf().get('Interfaces filter') try: iface_regex = re.compile(iface_filter) except Exception as e: logger.warning("Cannot parse regex for interface filter: {}".format(e)) iface_regex = re.compile('.*') for interface in interfaces: name = interface.get('NAME') mac = interface.get('MAC') ips = interface.get('IP') mtu = interface.get('MTU') description = interface.get('DESCR') iface_type = interface.get('TYPE') iface_state = interface.get('STATE') # TODO: add a bonding support iface_master = interface.get('BOND') # Check interface filter if not iface_regex.match(name): logger.debug("Iface {} not match with regex".format(name)) continue # Get interface from device - for check if exist ifaces = device.interfaces.filter(name=name) if ifaces: logger.info( "Interface {} is exist on device {}, will update".format( name, device.name)) # TODO: I think, that only one item will be in filter, but need to add check for it iface = ifaces[0] else: logger.info( "Interface {} is not exist on device {}, will create new". format(name, device.name)) iface = Interface(name=name) iface.device = device logger.info( "Will be save next parameters: Name:{name}, MAC: {mac}, MTU: {mtu}, Descr: {description}" .format(name=name, mac=mac, mtu=mtu, description=description)) if description: iface.description = description else: iface.description = '' iface.mac_address = mac # MTU should be less 32767 if int(mtu) < MAX_MTU: iface.mtu = mtu logger.info("Interface state is {}".format(iface_state)) iface.enabled = 'up' in iface_state.lower() iface.form_factor = _get_interface_type(name) try: iface.save() except Exception as e: logger.error("Cannot save interface, error is {}".format(e)) else: count += 1 logger.info("Interface {} was succesfully saved".format( name, device.name)) try: _connect_interface(iface) except: logger.error("Problem with connection function") # IP syncing if len(ips) > 0: for address in ips: addr = IPAddress() addr.interface = iface logger.info("Address is: {}".format(addr)) # TODO: Need a test ipv6 addresses try: # tries to determine is this address exist if iface.ip_addresses.filter(address=address): continue addr.address = IPNetwork(address) addr.save() except: logger.warning( "Cannot set address {} on interface".format(address)) if count == 0: return False, "Can't update any interface, see a log for details" return True, "Successfully updated {} interfaces".format(count)
def setUp(self): user = create_test_user(permissions=['dcim.view_cable']) self.client = Client() self.client.force_login(user) site = Site(name='Site 1', slug='site-1') site.save() manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1') manufacturer.save() devicetype = DeviceType(model='Device Type 1', manufacturer=manufacturer) devicetype.save() devicerole = DeviceRole(name='Device Role 1', slug='device-role-1') devicerole.save() device1 = Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole) device1.save() device2 = Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole) device2.save() iface1 = Interface(device=device1, name='Interface 1', type=IFACE_TYPE_1GE_FIXED) iface1.save() iface2 = Interface(device=device1, name='Interface 2', type=IFACE_TYPE_1GE_FIXED) iface2.save() iface3 = Interface(device=device1, name='Interface 3', type=IFACE_TYPE_1GE_FIXED) iface3.save() iface4 = Interface(device=device2, name='Interface 1', type=IFACE_TYPE_1GE_FIXED) iface4.save() iface5 = Interface(device=device2, name='Interface 2', type=IFACE_TYPE_1GE_FIXED) iface5.save() iface6 = Interface(device=device2, name='Interface 3', type=IFACE_TYPE_1GE_FIXED) iface6.save() Cable(termination_a=iface1, termination_b=iface4, type=CABLE_TYPE_CAT6).save() Cable(termination_a=iface2, termination_b=iface5, type=CABLE_TYPE_CAT6).save() Cable(termination_a=iface3, termination_b=iface6, type=CABLE_TYPE_CAT6).save()
def setUpTestData(cls): site = Site.objects.create(name='Site 1', slug='site-1') devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') clustertype = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1') cluster = Cluster.objects.create(name='Cluster 1', type=clustertype, site=site) virtualmachines = ( VirtualMachine(name='Virtual Machine 1', cluster=cluster, role=devicerole), VirtualMachine(name='Virtual Machine 2', cluster=cluster, role=devicerole), ) VirtualMachine.objects.bulk_create(virtualmachines) Interface.objects.bulk_create([ Interface(virtual_machine=virtualmachines[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_VIRTUAL), Interface(virtual_machine=virtualmachines[0], name='Interface 2', type=InterfaceTypeChoices.TYPE_VIRTUAL), Interface(virtual_machine=virtualmachines[0], name='Interface 3', type=InterfaceTypeChoices.TYPE_VIRTUAL), ]) vlans = ( VLAN(vid=1, name='VLAN1', site=site), VLAN(vid=101, name='VLAN101', site=site), VLAN(vid=102, name='VLAN102', site=site), VLAN(vid=103, name='VLAN103', site=site), ) VLAN.objects.bulk_create(vlans) cls.form_data = { 'virtual_machine': virtualmachines[1].pk, 'name': 'Interface X', 'type': InterfaceTypeChoices.TYPE_VIRTUAL, 'enabled': False, 'mgmt_only': False, 'mac_address': EUI('01-02-03-04-05-06'), 'mtu': 2000, 'description': 'New description', 'mode': InterfaceModeChoices.MODE_TAGGED, 'untagged_vlan': vlans[0].pk, 'tagged_vlans': [v.pk for v in vlans[1:4]], 'tags': 'Alpha,Bravo,Charlie', } cls.bulk_create_data = { 'virtual_machine': virtualmachines[1].pk, 'name_pattern': 'Interface [4-6]', 'type': InterfaceTypeChoices.TYPE_VIRTUAL, 'enabled': False, 'mgmt_only': False, 'mac_address': EUI('01-02-03-04-05-06'), 'mtu': 2000, 'description': 'New description', 'mode': InterfaceModeChoices.MODE_TAGGED, 'untagged_vlan': vlans[0].pk, 'tagged_vlans': [v.pk for v in vlans[1:4]], 'tags': 'Alpha,Bravo,Charlie', } cls.bulk_edit_data = { 'virtual_machine': virtualmachines[1].pk, 'enabled': False, 'mtu': 2000, 'description': 'New description', 'mode': InterfaceModeChoices.MODE_TAGGED, # 'untagged_vlan': vlans[0].pk, # 'tagged_vlans': [v.pk for v in vlans[1:4]], } cls.csv_data = ( "device,name,type", "Device 1,Interface 4,1000BASE-T (1GE)", "Device 1,Interface 5,1000BASE-T (1GE)", "Device 1,Interface 6,1000BASE-T (1GE)", )
def setUpTestData(cls): cluster_types = ( ClusterType(name='Cluster Type 1', slug='cluster-type-1'), ClusterType(name='Cluster Type 2', slug='cluster-type-2'), ClusterType(name='Cluster Type 3', slug='cluster-type-3'), ) ClusterType.objects.bulk_create(cluster_types) cluster_groups = ( ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'), ClusterGroup(name='Cluster Group 2', slug='cluster-group-2'), ClusterGroup(name='Cluster Group 3', slug='cluster-group-3'), ) ClusterGroup.objects.bulk_create(cluster_groups) regions = ( Region(name='Test Region 1', slug='test-region-1'), Region(name='Test Region 2', slug='test-region-2'), Region(name='Test Region 3', slug='test-region-3'), ) # Can't use bulk_create for models with MPTT fields for r in regions: r.save() sites = ( Site(name='Test Site 1', slug='test-site-1', region=regions[0]), Site(name='Test Site 2', slug='test-site-2', region=regions[1]), Site(name='Test Site 3', slug='test-site-3', region=regions[2]), ) Site.objects.bulk_create(sites) clusters = ( Cluster(name='Cluster 1', type=cluster_types[0], group=cluster_groups[0], site=sites[0]), Cluster(name='Cluster 2', type=cluster_types[1], group=cluster_groups[1], site=sites[1]), Cluster(name='Cluster 3', type=cluster_types[2], group=cluster_groups[2], site=sites[2]), ) Cluster.objects.bulk_create(clusters) platforms = ( Platform(name='Platform 1', slug='platform-1'), Platform(name='Platform 2', slug='platform-2'), Platform(name='Platform 3', slug='platform-3'), ) Platform.objects.bulk_create(platforms) roles = ( DeviceRole(name='Device Role 1', slug='device-role-1'), DeviceRole(name='Device Role 2', slug='device-role-2'), DeviceRole(name='Device Role 3', slug='device-role-3'), ) DeviceRole.objects.bulk_create(roles) tenant_groups = ( TenantGroup(name='Tenant group 1', slug='tenant-group-1'), TenantGroup(name='Tenant group 2', slug='tenant-group-2'), TenantGroup(name='Tenant group 3', slug='tenant-group-3'), ) for tenantgroup in tenant_groups: tenantgroup.save() tenants = ( Tenant(name='Tenant 1', slug='tenant-1', group=tenant_groups[0]), Tenant(name='Tenant 2', slug='tenant-2', group=tenant_groups[1]), Tenant(name='Tenant 3', slug='tenant-3', group=tenant_groups[2]), ) Tenant.objects.bulk_create(tenants) vms = ( VirtualMachine(name='Virtual Machine 1', cluster=clusters[0], platform=platforms[0], role=roles[0], tenant=tenants[0], status=VirtualMachineStatusChoices.STATUS_ACTIVE, vcpus=1, memory=1, disk=1, local_context_data={"foo": 123}), VirtualMachine(name='Virtual Machine 2', cluster=clusters[1], platform=platforms[1], role=roles[1], tenant=tenants[1], status=VirtualMachineStatusChoices.STATUS_STAGED, vcpus=2, memory=2, disk=2), VirtualMachine(name='Virtual Machine 3', cluster=clusters[2], platform=platforms[2], role=roles[2], tenant=tenants[2], status=VirtualMachineStatusChoices.STATUS_OFFLINE, vcpus=3, memory=3, disk=3), ) VirtualMachine.objects.bulk_create(vms) interfaces = ( Interface(virtual_machine=vms[0], name='Interface 1', mac_address='00-00-00-00-00-01'), Interface(virtual_machine=vms[1], name='Interface 2', mac_address='00-00-00-00-00-02'), Interface(virtual_machine=vms[2], name='Interface 3', mac_address='00-00-00-00-00-03'), ) Interface.objects.bulk_create(interfaces)
def handle(self, *args, **options): # First, query for the device by name. try: device = Device.objects.get(name=options['name']) except Device.DoesNotExist: self.stdout.write(f"Unable to find device: {options['name']}") return # If an IP address was specified, then configure the device with it. _ip = options['ip'] if _ip is not None: # Make sure there's an interface named "mgmt" # If there isn't, then create one. mgmt_iface = next( (True for iface in device.vc_interfaces() if iface.name == 'mgmt'), None) if not mgmt_iface: if options['dry_run']: self.stdout.write( 'Would have created a managment interface called mgmt') else: mgmt_iface = Interface( device=device, name='mgmt', type=InterfaceTypeChoices.TYPE_VIRTUAL) mgmt_iface.save() # Make sure the specific IP address exists and is on the mgmt interface. try: _ip = options['ip'] mgmt_ip = IPAddress.objects.get(address=_ip) # If the IP exists, make sure it's currently not assigned to another interface. if mgmt_ip.interface is not None: if mgmt_ip.interface.name != 'mgmt' and mgmt_ip.interface.device.id != device.id: self.stdout.write( f"IP Address {_ip} is already assigned to {mgmt_ip.interface.device.name}" ) return # Otherwise, add the IP to the interface. else: if options['dry_run']: self.stdout.write( f"Would have added {mgmt_ip} to the mgmt interface" ) else: mgmt_ip.interface = mgmt_iface mgmt_ip.save() except IPAddress.DoesNotExist: # If the IP doesn't exist, create it and link it to the mgmt interfae. if options['dry_run']: self.stdout.write( f"Would have created IP address {options['ip']} and assigned it to the mgmt interface" ) else: mgmt_ip = IPAddress(address=options['ip'], interface=mgmt_iface) mgmt_ip.save() # Ensure the primary IP address of the device is set to the mgmt IP. if device.primary_ip4 is None or device.primary_ip4.id != mgmt_ip.id: if options['dry_run']: self.stdout.write( f"Would have assigned {mgmt_ip} as the primary IP of the device" ) else: device.primary_ip4 = mgmt_ip device.save()
def syncInterfaces(device, connection, iface_regex): ''' Get interfaces from device and add|update it on netbox ''' interfaces = connection.get_interfaces() print("Connection complete, number of interfaces {}".format( len(interfaces))) for if_name in interfaces.keys(): # Cheking is interface matching regex if re.match(iface_regex, if_name): if_type = getInterfaceType(if_name) # and state (up/down) state = (interfaces[if_name]['is_enabled'] and interfaces[if_name]['is_up']) intf = device.interfaces.filter(name=if_name) # I cannot found now a way how to do it without two code block =\ if intf.count() == 0: # if no interface present in device, create new print("Create new interface {}".format(if_name)) iface = Interface(name=if_name) iface.description = interfaces[if_name]['description'] iface.mac_address = interfaces[if_name]['mac_address'] iface.enabled = state iface.form_factor = if_type iface.device = device iface.save() # Try to connect interface by description connect_interface(iface) else: # or get current iface and update them print("Update interface {}".format(if_name)) iface = intf[0] iface.description = interfaces[if_name]['description'] iface.mac_address = interfaces[if_name]['mac_address'] iface.enabled = state #iface.form_factor = if_type iface.save() # Try to connect interface by description connect_interface(iface) else: pass