def test_hostname(self): from ralph.util.network import hostname # existing host self.assertIsNotNone(hostname(IP2HOST_IP)) self.assertIsNotNone( re.match(IP2HOST_HOSTNAME_REGEX, hostname(IP2HOST_IP))) # non-existent host self.assertIsNone(hostname(NON_EXISTENT_HOST_IP))
def test_hostname(self): from ralph.util.network import hostname # existing host self.assertIsNotNone(hostname(IP2HOST_IP)) self.assertIsNotNone(re.match(IP2HOST_HOSTNAME_REGEX, hostname(IP2HOST_IP))) # non-existent host self.assertIsNone(hostname(NON_EXISTENT_HOST_IP))
def save(self, allow_device_change=True, *args, **kwargs): if not allow_device_change: self.assert_same_device() if not self.address: self.address = network.hostname(self.hostname, reverse=True) if not self.hostname: self.hostname = network.hostname(self.address) self.number = int(ipaddr.IPAddress(self.address)) try: self.network = Network.from_ip(self.address) except IndexError: self.network = None super(IPAddress, self).save(*args, **kwargs)
def _run_ssh_catalyst(ip): ssh = _connect_ssh(ip) try: raw = '\n'.join(ssh.cisco_command("show inventory")) finally: ssh.close() inventory = list(cisco_inventory(raw)) serials = [inv['sn'] for inv in inventory] try: dev = Device.objects.get(sn__in=serials) except Device.DoesNotExist: dev_inv = inventory[0] dev = Device.create(sn=dev_inv['sn'], model_name='Cisco %s' % dev_inv['pid'], model_type=DeviceType.switch, name=dev_inv['descr'][:255]) dev.save(update_last_seen=True) for inv in inventory: cisco_component(dev, inv) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.device = dev ip_address.is_management = True ip_address.save(update_last_seen=True) return dev.name
def _run_ssh_catalyst(ip): ssh = _connect_ssh(ip) try: raw = "\n".join(ssh.cisco_command("show inventory")) finally: ssh.close() inventory = list(cisco_inventory(raw)) serials = [inv["sn"] for inv in inventory] try: dev = Device.objects.get(sn__in=serials) except Device.DoesNotExist: dev_inv = inventory[0] dev = Device.create( sn=dev_inv["sn"], model_name="Cisco %s" % dev_inv["pid"], model_type=DeviceType.switch, name=dev_inv["descr"][:255], ) dev.save(update_last_seen=True) for inv in inventory: cisco_component(dev, inv) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.device = dev ip_address.is_management = True ip_address.save(update_last_seen=True) return dev.name
def _run_ssh_catalyst(ip): ssh = _connect_ssh(ip) try: mac = '\n'.join(ssh.cisco_command( "show version | include Base ethernet MAC Address" )) raw = '\n'.join(ssh.cisco_command("show inventory")) finally: ssh.close() mac = mac.strip() if mac.startswith("Base ethernet MAC Address") and ':' in mac: ethernets = [ Eth( "Base ethernet MAC Address", mac.split(':', 1)[1].strip(), None, ), ] else: ethernets = None inventory = list(cisco_inventory(raw)) serials = [inv['sn'] for inv in inventory] dev_inv = inventory[0] try: dev = Device.objects.get(sn__in=serials) except MultipleObjectsReturned: raise Error( "Stacked devices with serials %r should be merged.", serials, ) except Device.DoesNotExist: sn = dev_inv['sn'] model_name='Cisco %s' % dev_inv['pid'] else: # This is a stacked device, use the base device for it sn = dev.sn model_name = dev.model.name dev = Device.create( ethernets=ethernets, sn=sn, model_name=model_name, model_type=DeviceType.switch, name=dev_inv['descr'][:255], ) dev.save(update_last_seen=True) for inv in inventory: cisco_component(dev, inv) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.device = dev ip_address.is_management = True ip_address.save(update_last_seen=True) return dev.name
def save(self, allow_device_change=True, *args, **kwargs): if not allow_device_change: self.assert_same_device() if not self.address: self.address = network.hostname(self.hostname, reverse=True) if not self.hostname: self.hostname = network.hostname(self.address) self.number = int(ipaddr.IPAddress(self.address)) try: self.network = Network.from_ip(self.address) except IndexError: self.network = None if self.network and self.network.ignore_addresses: self.device = None ip = ipaddr.IPAddress(self.address) self.is_public = not ip.is_private super(IPAddress, self).save(*args, **kwargs)
def _add_dev_system(ip, pairs, parent, raw, counts, dev_id): dev = _dev(DeviceType.blade_system, pairs, parent, raw) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.device = dev ip_address.is_management = True # FIXME: how do we know for sure? ip_address.save(update_last_seen=True) # no priorities for IP addresses return dev
def scan_address(ip_address, **kwargs): if 'nx-os' in (kwargs.get('snmp_name', '') or '').lower(): raise NoMatchError('Incompatible Nexus found.') if kwargs.get('http_family') not in ('Unspecified', 'Cisco'): raise NoMatchError('It is not Cisco.') ssh = _connect_ssh(ip_address) hostname = network.hostname(ip_address) try: ssh.cisco_command('terminal length 500') mac = '\n'.join( ssh.cisco_command( "show version | include Base ethernet MAC Address", )) raw = '\n'.join(ssh.cisco_command("show inventory")) subswitches = get_subswitches(ssh.cisco_command("show version"), hostname, ip_address) finally: ssh.close() matches = re.match('Base ethernet MAC Address\s+:\s*([0-9aA-Z:]+)', mac) if matches.groups(): mac = matches.groups()[0] inventory = list(cisco_inventory(raw)) dev_inv, parts = inventory[0], inventory[1:] sn = dev_inv['sn'] result = get_base_result_template('ssh_cisco_catalyst') if subswitches: # virtual switch doesn't have own unique id, reuse first from stack sn += '-virtual' model_name = 'Virtual Cisco Catalyst %s' % dev_inv['pid'] model_type = DeviceType.switch_stack else: model_name = 'Cisco Catalyst %s' % dev_inv['pid'] model_type = DeviceType.switch result.update({ 'status': 'success', 'device': { 'hostname': hostname if hostname else ip_address, 'model_name': model_name, 'type': model_type.raw, 'management_ip_addresses': [ip_address], 'parts': [{ 'serial_number': part['sn'], 'name': part['name'], 'label': part['descr'], } for part in parts], }, }) if sn not in SERIAL_BLACKLIST: result['device']['serial_number'] = sn if subswitches: result['device']['subdevices'] = subswitches else: result['device']['mac_addresses'] = [mac] return result
def scan_address(ip_address, **kwargs): if 'nx-os' in (kwargs.get('snmp_name', '') or '').lower(): raise NoMatchError('Incompatible Nexus found.') if kwargs.get('http_family') not in ('Unspecified', 'Cisco'): raise NoMatchError('It is not Cisco.') ssh = _connect_ssh(ip_address) hostname = network.hostname(ip_address) try: ssh.cisco_command('terminal length 500') mac = '\n'.join(ssh.cisco_command( "show version | include Base ethernet MAC Address", )) raw = '\n'.join(ssh.cisco_command("show inventory")) subswitches = get_subswitches( ssh.cisco_command("show version"), hostname, ip_address ) finally: ssh.close() matches = re.match( 'Base ethernet MAC Address\s+:\s*([0-9aA-Z:]+)', mac) if matches.groups(): mac = matches.groups()[0] inventory = list(cisco_inventory(raw)) dev_inv, parts = inventory[0], inventory[1:] sn = dev_inv['sn'] result = get_base_result_template('ssh_cisco_catalyst') if subswitches: # virtual switch doesn't have own unique id, reuse first from stack sn += '-virtual' model_name = 'Virtual Cisco Catalyst %s' % dev_inv['pid'] model_type = DeviceType.switch_stack else: model_name = 'Cisco Catalyst %s' % dev_inv['pid'] model_type = DeviceType.switch result.update({ 'status': 'success', 'device': { 'hostname': hostname if hostname else ip_address, 'model_name': model_name, 'type': model_type.raw, 'management_ip_addresses': [ip_address], 'parts': [{ 'serial_number': part['sn'], 'name': part['name'], 'label': part['descr'], } for part in parts], }, }) if sn not in SERIAL_BLACKLIST: result['device']['serial_number'] = sn if subswitches: result['device']['subdevices'] = subswitches else: result['device']['mac_addresses'] = [MACAddressField.normalize(mac)] return result
def scan_address(address, **kwargs): messages = [] data = get_base_result_template('dns_hostname', messages) hostname = network.hostname(address) if hostname: data['device'] = { 'hostname': hostname, } data['status'] = 'success' else: data['status'] = 'error' return data
def _run_ipmi(ip): try: ipmi = IPMI(ip) fru = ipmi.get_fru() except AuthError: try: ipmi = IPMI(ip, 'ADMIN') fru = ipmi.get_fru() except AuthError: ipmi = IPMI(ip, 'ADMIN', 'ADMIN') fru = ipmi.get_fru() mc = ipmi.get_mc() top = fru['/SYS'] if not top: top = fru['Builtin FRU Device'] if not top: raise AnswerError('Incompatible answer.') name, name_clean = _clean(top['Product Name']) sn, sn_clean = _clean(top['Product Serial']) if sn in SERIAL_BLACKLIST: sn = None model_type = DeviceType.rack_server if name.lower().startswith('ipmi'): model_type = DeviceType.unknown mac = ipmi.get_mac() if mac: ethernets = [Eth(label='IPMI MAC', mac=mac, speed=0)] else: ethernets = [] ethernets.extend(_get_ipmi_ethernets(fru)) dev = Device.create(ethernets=ethernets, priority=SAVE_PRIORITY, sn=sn, model_name=name.title(), model_type=model_type) firmware = mc.get('Firmware Revision') if firmware: dev.mgmt_firmware = 'rev %s' % firmware _add_ipmi_lan(dev, mac) _add_ipmi_components(dev, fru) dev.save(update_last_seen=True, priority=SAVE_PRIORITY) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) ip_address.device = dev ip_address.is_management = True if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.snmp_name = name ip_address.save(update_last_seen=True) # no priorities for IP addresses return name
def scan_address(ip_address, **kwargs): status = 'success' ssh = _connect_ssh(ip_address) try: mac = '\n'.join( ssh.cisco_command( "show version | include Base ethernet MAC Address", )) raw = '\n'.join(ssh.cisco_command("show inventory")) finally: ssh.close() mac = mac.strip() if mac.startswith("Base ethernet MAC Address") and ':' in mac: mac = mac.split(':', 1)[1].strip().replace(":", "") else: ethernets = None inventory = list(cisco_inventory(raw)) serials = [inv['sn'] for inv in inventory] dev_inv = inventory[0] model_name = 'Cisco Catalyst %s' % dev_inv['pid'] sn = dev_inv['sn'] model_type = DeviceType.switch device = { 'hostname': network.hostname(ip_address), 'model_name': model_name, 'type': str(model_type), 'serial_number': sn, 'mac_adresses': [ mac, ], 'management_ip_addresses': [ ip_address, ], } parts = inventory[1:] device['parts'] = [] for p in parts: part = { 'serial_number': p['sn'], 'name': p['name'], 'label': p['descr'], } device['parts'].append(part) ret = { 'status': status, 'device': device, } tpl = get_base_result_template('ssh_cisco_catalyst') tpl.update(ret) return tpl
def get_ip_hostname_sets(ip): hostname_set = {network.hostname(ip)} try: ip_address = IPAddress.objects.get(address=ip) if ip_address.device: ip_set = set() for ip in ip_address.device.ipaddress_set.all(): ip_set.add(ip.address) if ip.hostname: hostname_set.add(ip.hostname) else: ip_set = {ip} except IPAddress.DoesNotExist: ip_set = {ip} return ip_set, hostname_set
def ping(**kwargs): ip = kwargs['ip'] is_up = False if network.ping(str(ip)) is None: message = 'down.' else: is_up = True message = 'up!' ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) hostname = network.hostname(ip) if hostname: ip_address.hostname = hostname ip_address.dns_info = '\n'.join(network.descriptions(hostname)) kwargs['community'] = ip_address.snmp_community ip_address.save(update_last_seen=True) return is_up, message, kwargs
def ping(**kwargs): ip = kwargs['ip'] is_up = False if network.ping(str(ip)) is None: message = 'down.' else: is_up = True message = 'up!' ip_address, created = IPAddress.concurrent_get_or_create( address=str(ip)) hostname = network.hostname(ip) if hostname: ip_address.hostname = hostname ip_address.dns_info = '\n'.join(network.descriptions(hostname)) kwargs['community'] = ip_address.snmp_community ip_address.save(update_last_seen=True) return is_up, message, kwargs
def scan_address(ip_address, **kwargs): status = 'success' ssh = _connect_ssh(ip_address) try: mac = '\n'.join(ssh.cisco_command( "show version | include Base ethernet MAC Address", )) raw = '\n'.join(ssh.cisco_command("show inventory")) finally: ssh.close() mac = mac.strip() if mac.startswith("Base ethernet MAC Address") and ':' in mac: mac = mac.split(':', 1)[1].strip().replace(":", "") else: ethernets = None inventory = list(cisco_inventory(raw)) serials = [inv['sn'] for inv in inventory] dev_inv = inventory[0] model_name='Cisco Catalyst %s' % dev_inv['pid'] sn = dev_inv['sn'] model_type=DeviceType.switch device = { 'hostname': network.hostname(ip_address), 'model_name': model_name, 'type': str(model_type), 'serial_number': sn, 'mac_adresses': [mac, ], 'management_ip_addresses': [ip_address, ], } parts = inventory[1:] device['parts'] = [] for p in parts: part = { 'serial_number': p['sn'], 'name': p['name'], 'label': p['descr'], } device['parts'].append(part) ret = { 'status': status, 'device': device, } tpl = get_base_result_template('ssh_cisco_catalyst') tpl.update(ret) return tpl
def _handle(self, *args, **options): """Actual handling of the request.""" args = list(args) discover = options['discover'] new_networks = set() if options['dc']: for dc in options['dc'].split(','): dc = dc.strip() new_networks.update(n.address for n in Network.objects.filter( data_center__name__iexact=dc)) if options['queues']: for queue in options['queues'].split(','): queue = queue.strip() new_networks.update(n.address for n in Network.objects.filter( queue__name__iexact=queue)) if new_networks: args.extend(new_networks) if not args: discover.all() return error = False for arg in args: try: addr = IPNetwork(arg) except ValueError: try: discover.network(arg) except Network.DoesNotExist: ip = network.hostname(arg, reverse=True) if ip: try: discover.single(ip) except NoQueueError as e: print(e) else: print('Hostname or network unknown:', arg) error = True else: if addr.numhosts > 1: discover.network(addr) else: discover.single(addr.ip) print() if error: sys.exit(2)
def puppet(**kwargs): if not settings.PUPPET_DB_URL: return False, "not configured", kwargs ip = str(kwargs['ip']) ip_set, hostname_set = get_ip_hostname_sets(ip) db = connect_db() facts = get_all_facts_by_ip_set(db, ip_set) if not facts and hostname_set: facts = get_all_facts_by_hostname_set(db, hostname_set) if not facts: return False, "host config not found.", kwargs try: is_virtual = is_host_virtual(facts) try: lshw = facts['lshw'] except KeyError: dev, dev_name = parse_facts(facts, is_virtual) else: dev, dev_name = parse_lshw(lshw, facts, is_virtual) except MySQLdb.OperationalError as e: if e.args[0] in (1205, 1213) and 'try restarting transaction' in e.args[1]: time.sleep(random.choice(range(10)) + 1) raise plugin.Restart(unicode(e), kwargs) raise if not dev: return False, dev_name, kwargs parse_wwn(facts, dev) parse_smartctl(facts, dev) parse_hpacu(facts, dev) parse_megaraid(facts, dev) parse_uptime(facts, dev) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) ip_address.device, message = dev, dev_name if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.last_puppet = datetime.datetime.now() ip_address.save(update_last_seen=True) # no priorities for IP addresses handle_facts_os(dev, facts, is_virtual) return True, message, kwargs
def _handle(self, *args, **options): """Actual handling of the request.""" args = list(args) discover = options['discover'] new_networks = set() if options['dc']: for dc in options['dc'].split(','): dc = dc.strip() new_networks.update(n.address for n in Network.objects.filter( data_center__name__iexact=dc)) if options['queues']: for queue in options['queues'].split(','): queue = queue.strip() new_networks.update( n.address for n in Network.objects.filter(queue__name__iexact=queue)) if new_networks: args.extend(new_networks) if not args: discover.all() return error = False for arg in args: try: addr = IPNetwork(arg) except ValueError: try: discover.network(arg) except Network.DoesNotExist: ip = network.hostname(arg, reverse=True) if ip: discover.single({'ip': ip}) else: print('Hostname or network unknown:', arg) error = True else: if addr.numhosts > 1: discover.network(addr) else: discover.single({'ip': addr.ip}) print() if error: sys.exit(2)
def _run_ipmi(ip): try: ipmi = IPMI(ip) fru = ipmi.get_fru() except AuthError: try: ipmi = IPMI(ip, 'ADMIN') fru = ipmi.get_fru() except AuthError: ipmi = IPMI(ip, 'ADMIN', 'ADMIN') fru = ipmi.get_fru() mc = ipmi.get_mc() top = fru['/SYS'] if not top: top = fru['Builtin FRU Device'] if not top: raise AnswerError('Incompatible answer.') name, sn, model_type = _get_base_device_info(top) mac = ipmi.get_mac() if mac: ethernets = [Eth(label='IPMI MAC', mac=mac, speed=0)] else: ethernets = [] ethernets.extend(_get_ipmi_ethernets(fru)) dev = Device.create(ethernets=ethernets, priority=SAVE_PRIORITY, sn=sn, model_name=name.title(), model_type=model_type) firmware = mc.get('Firmware Revision') if firmware: dev.mgmt_firmware = 'rev %s' % firmware _add_ipmi_lan(dev, mac) _add_ipmi_components(dev, fru) dev.save(update_last_seen=True, priority=SAVE_PRIORITY) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) ip_address.device = dev ip_address.is_management = True if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.snmp_name = name ip_address.save(update_last_seen=True) return name
def puppet(**kwargs): if not settings.PUPPET_API_URL and not settings.PUPPET_DB_URL: return False, "not configured", kwargs ip = str(kwargs['ip']) ip_set, hostname_set = get_ip_hostname_sets(ip) if settings.PUPPET_DB_URL: puppet = PuppetDBProvider() else: puppet = PuppetAPIProvider() facts = puppet.get_facts(ip_set, hostname_set) if not facts: return False, "host config not found.", kwargs is_virtual = is_host_virtual(facts) try: lshw = facts['lshw'] except KeyError: dev, dev_name = parse_facts(facts, is_virtual) else: dev, dev_name = parse_lshw(lshw, facts, is_virtual) if not dev: return False, dev_name, kwargs parse_wwn(facts, dev) parse_3ware(facts, dev) parse_smartctl(facts, dev) parse_hpacu(facts, dev) parse_megaraid(facts, dev) parse_uptime(facts, dev) ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) ip_address.device, message = dev, dev_name if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.last_puppet = datetime.datetime.now() ip_address.save(update_last_seen=True) # no priorities for IP addresses handle_facts_os(dev, facts, is_virtual) handle_facts_packages(dev, facts.get('packages')) return True, message, kwargs
def _add_hp_oa_devices(devices, device_type, parent=None): if devices and not isinstance(devices, list): devices = [devices] for i, device in enumerate(devices): bay = device['BAY']['CONNECTION2']['BLADESYMBOLICNUMBER'] or str(device['BAY']['CONNECTION']) name = device['PN'].strip() or device['SPN'].strip() if not name.startswith('HP'): name = 'HP ' + name firmware = str(device.get('FWRI', '')) sn = device['SN'].strip() if sn in SERIAL_BLACKLIST: sn = None if not sn: sn = device['BSN'].strip() if sn in SERIAL_BLACKLIST: sn = None try: ip = network.validate_ip(device['MGMTIPADDR']) except ValueError: continue ip_address, created = IPAddress.concurrent_get_or_create(address=str(ip)) if created: ip_address.hostname = network.hostname(ip_address.address) ip_address.snmp_name = name ip_address.save(update_last_seen=True) # no priorities for IP addresses if device_type == DeviceType.management: ip_address.is_management = True if parent and not parent.management: parent.management = ip_address parent.save(priority=SAVE_PRIORITY) extra = name model, mcreated = ComponentModel.concurrent_get_or_create( type=ComponentType.management.id, extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) model.name = name model.save(priority=SAVE_PRIORITY) component, created = GenericComponent.concurrent_get_or_create( device=parent, sn=sn) component.model = model component.label = name component.save(priority=SAVE_PRIORITY) if ip: ip_address.is_management = True ip_address.device = parent ip_address.save() # no priorities for IP addresses continue if device_type == DeviceType.switch and 'SAN' in name: device_type = DeviceType.fibre_channel_switch ethernets = list(_get_ethernets(device)) if not (ip and name and (sn or ethernets)): continue dev = None if ip and device_type in (DeviceType.switch, DeviceType.fibre_channel_switch): ip_addr, ip_created = IPAddress.concurrent_get_or_create(address=ip) if ip_addr.device: dev = ip_addr.device dev.parent = parent if dev is None: dev = Device.create(sn=sn, model_name=name, model_type=device_type, ethernets=ethernets, parent=parent, priority=SAVE_PRIORITY) if firmware: dev.hard_firmware = firmware if bay: name = '%s [%s]' % (name, bay) if bay: if 'A' in bay or 'B' in bay: dev.chassis_position = int(bay[:-1]) if bay[-1] == 'A': dev.chassis_position += 1000 elif bay[-1] == 'B': dev.chassis_position += 2000 else: dev.chassis_position = int(bay) dev.position = bay else: dev.chassis_position = i + 1 dev.save(update_last_seen=True, priority=SAVE_PRIORITY) ip_address.device = dev ip_address.save(update_last_seen=True) # no priorities for IP addresses
def _handle(self, *args, **options): """Actual handling of the request.""" args = list(args) discover = options['discover'] new_networks = set() if options['dc']: for dc in options['dc'].split(','): dc = dc.strip() new_networks.update(n.address for n in Network.objects.filter( data_center__name__iexact=dc)) if options['queues']: for queue in options['queues'].split(','): queue = queue.strip() for environment in Environment.objects.filter( queue__name__iexact=queue, ): new_networks.update( net.address for net in environment.network_set.all(), ) if options['environments']: for environment_name in options['environments'].split(','): environment_name = environment_name.strip() try: environment = Environment.objects.get( name__iexact=environment_name, queue__isnull=False, ) except Environment.DoesNotExist: print( "Environment %s does not have configured queue." % ( environment_name, ), file=sys.stderr, ) sys.exit(2) else: new_networks.update( net.address for net in environment.network_set.all(), ) if new_networks: args.extend(new_networks) if not args: discover.all() return error = False for arg in args: try: addr = IPNetwork(arg) except ValueError: try: discover.network(arg) except Network.DoesNotExist: ip = network.hostname(arg, reverse=True) if ip: try: discover.single(ip) except NoQueueError as e: print(e) else: print('Hostname or network unknown:', arg) error = True else: if addr.numhosts > 1: discover.network(addr) else: discover.single(addr.ip) print() if error: sys.exit(2)