def _validate_interfaces(self, interfaces, data=None): """Validate interfaces on correctness and suitability. :return: dict interface name -> dict with keys 'mac' and 'ip' """ if not interfaces: raise utils.Error(_('No interfaces supplied by the ramdisk'), data=data) pxe_mac = utils.get_pxe_mac(data) if not pxe_mac and CONF.processing.add_ports == 'pxe': LOG.warning(_LW('No boot interface provided in the introspection ' 'data, will add all ports with IP addresses')) result = {} for name, iface in interfaces.items(): mac = iface.get('mac') ip = iface.get('ip') if not mac: LOG.debug('Skipping interface %s without link information', name, data=data) continue if not utils.is_valid_mac(mac): LOG.warning(_LW('MAC %(mac)s for interface %(name)s is not ' 'valid, skipping'), {'mac': mac, 'name': name}, data=data) continue mac = mac.lower() if name == 'lo' or (ip and netaddr.IPAddress(ip).is_loopback()): LOG.debug('Skipping local interface %s', name, data=data) continue if (CONF.processing.add_ports == 'pxe' and pxe_mac and mac != pxe_mac): LOG.debug('Skipping interface %s as it was not PXE booting', name, data=data) continue elif CONF.processing.add_ports != 'all' and not ip: LOG.debug('Skipping interface %s as it did not have ' 'an IP address assigned during the ramdisk run', name, data=data) continue result[name] = {'ip': ip, 'mac': mac.lower()} if not result: raise utils.Error(_('No suitable interfaces found in %s') % interfaces, data=data) return result
def _get_interfaces(self, data=None): """Convert inventory to a dict with interfaces. :return: dict interface name -> dict with keys 'mac' and 'ip' """ result = {} inventory = utils.get_inventory(data) pxe_mac = utils.get_pxe_mac(data) for iface in inventory['interfaces']: name = iface.get('name') mac = iface.get('mac_address') ip = iface.get('ipv4_address') client_id = iface.get('client_id') if not name: LOG.error('Malformed interface record: %s', iface, data=data) continue if not mac: LOG.debug('Skipping interface %s without link information', name, data=data) continue if not netutils.is_valid_mac(mac): LOG.warning( 'MAC %(mac)s for interface %(name)s is ' 'not valid, skipping', { 'mac': mac, 'name': name }, data=data) continue mac = mac.lower() LOG.debug( 'Found interface %(name)s with MAC "%(mac)s", ' 'IP address "%(ip)s" and client_id "%(client_id)s"', { 'name': name, 'mac': mac, 'ip': ip, 'client_id': client_id }, data=data) result[name] = { 'ip': ip, 'mac': mac, 'client_id': client_id, 'pxe': (mac == pxe_mac) } return result
def _validate_interfaces(self, interfaces, data=None): """Validate interfaces on correctness and suitability. :return: dict interface name -> dict with keys 'mac' and 'ip' """ if not interfaces: raise utils.Error(_('No interfaces supplied by the ramdisk'), data=data) pxe_mac = utils.get_pxe_mac(data) if not pxe_mac and CONF.processing.add_ports == 'pxe': LOG.warning( _LW('No boot interface provided in the introspection ' 'data, will add all ports with IP addresses')) result = {} for name, iface in interfaces.items(): mac = iface.get('mac') ip = iface.get('ip') client_id = iface.get('client_id') if name == 'lo' or (ip and netaddr.IPAddress(ip).is_loopback()): LOG.debug('Skipping local interface %s', name, data=data) continue if (CONF.processing.add_ports == 'pxe' and pxe_mac and mac != pxe_mac): LOG.debug('Skipping interface %s as it was not PXE booting', name, data=data) continue elif CONF.processing.add_ports != 'all' and not ip: LOG.debug( 'Skipping interface %s as it did not have ' 'an IP address assigned during the ramdisk run', name, data=data) continue result[name] = { 'ip': ip, 'mac': mac.lower(), 'client_id': client_id } if not result: raise utils.Error(_('No suitable interfaces found in %s') % interfaces, data=data) return result
def _get_interfaces(self, data=None): """Convert inventory to a dict with interfaces. :return: dict interface name -> dict with keys 'mac' and 'ip' """ result = {} inventory = utils.get_inventory(data) pxe_mac = utils.get_pxe_mac(data) for iface in inventory['interfaces']: name = iface.get('name') mac = iface.get('mac_address') ipv4_address = iface.get('ipv4_address') ipv6_address = iface.get('ipv6_address') # NOTE(kaifeng) ipv6 address may in the form of fd00::1%enp2s0, # which is not supported by netaddr, remove the suffix if exists. if ipv6_address and '%' in ipv6_address: ipv6_address = ipv6_address.split('%')[0] ip = ipv4_address or ipv6_address client_id = iface.get('client_id') if not name: LOG.error('Malformed interface record: %s', iface, data=data) continue if not mac: LOG.debug('Skipping interface %s without link information', name, data=data) continue if not netutils.is_valid_mac(mac): LOG.warning('MAC %(mac)s for interface %(name)s is ' 'not valid, skipping', {'mac': mac, 'name': name}, data=data) continue mac = mac.lower() LOG.debug('Found interface %(name)s with MAC "%(mac)s", ' 'IP address "%(ip)s" and client_id "%(client_id)s"', {'name': name, 'mac': mac, 'ip': ip, 'client_id': client_id}, data=data) result[name] = {'ip': ip, 'mac': mac, 'client_id': client_id, 'pxe': (mac == pxe_mac)} return result
def _store_logs(introspection_data, node_info): logs = introspection_data.get('logs') if not logs: LOG.warning('No logs were passed by the ramdisk', data=introspection_data, node_info=node_info) return if not CONF.processing.ramdisk_logs_dir: LOG.warning( 'Failed to store logs received from the ramdisk ' 'because ramdisk_logs_dir configuration option ' 'is not set', data=introspection_data, node_info=node_info) return fmt_args = { 'uuid': node_info.uuid if node_info is not None else 'unknown', 'mac': (utils.get_pxe_mac(introspection_data) or 'unknown').replace(':', ''), 'dt': datetime.datetime.utcnow(), 'bmc': (utils.get_ipmi_address_from_data(introspection_data) or 'unknown') } file_name = CONF.processing.ramdisk_logs_filename_format.format(**fmt_args) try: if not os.path.exists(CONF.processing.ramdisk_logs_dir): os.makedirs(CONF.processing.ramdisk_logs_dir) with open(os.path.join(CONF.processing.ramdisk_logs_dir, file_name), 'wb') as fp: fp.write(base64.decode_as_bytes(logs)) except EnvironmentError: LOG.exception('Could not store the ramdisk logs', data=introspection_data, node_info=node_info) else: LOG.info('Ramdisk logs were stored in file %s', file_name, data=introspection_data, node_info=node_info)