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
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 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 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)