def getNetworkInterfaces(self): """ Returns list of interfaces on installer as discovered by 'facter interfaces'. List does not include 'lo' (loopback) device. Raises: NicNotFound """ cmd = 'facter --json interfaces' p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = json.load(p.stdout) retval = p.wait() if retval != 0 or 'interfaces' not in result: errmsg = 'Unable to find public NIC on installer' self.getLogger().error('[networkManager] ' + errmsg) raise NicNotFound(errmsg) return [ intfc for intfc in result['interfaces'].split(',') if intfc != 'lo' ]
def getProvisioningNicForNetwork(self, network, netmask): """ Raises: NicNotFound """ session = DbManager().openSession() try: installer_node = self.__getInstallerNode(session) nics = [ dbNic for dbNic in installer_node.hardwareprofile.nics if dbNic.network.address == network and dbNic.network.netmask == netmask ] if not nics: raise NicNotFound( 'Unable to find provisioning NIC for network [%s]' ' netmask [%s]' % (network, netmask)) return tortuga.objects.nic.Nic.getFromDbDict(nics[0].__dict__) except TortugaException as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession()
def getProvisioningNicForNetwork(self, session: Session, network: str, netmask: str) -> Nic: """ Raises: NicNotFound """ try: installer_node = self.__getInstallerNode(session) nics = [ dbNic for dbNic in installer_node.hardwareprofile.nics if dbNic.network.address == network and dbNic.network.netmask == netmask ] if not nics: raise NicNotFound( 'Unable to find provisioning NIC for network [%s]' ' netmask [%s]' % (network, netmask)) return tortuga.objects.nic.Nic.getFromDbDict(nics[0].__dict__) except TortugaException as ex: self._logger.exception(str(ex)) raise
def runCommand(self): self.parseArgs() with DbManager().session() as session: dbNode = NodesDbHandler().getNode(session, self._cm.getInstaller()) # Validate device name NetworkDevicesDbHandler().getNetworkDevice(session, self.getArgs().nic) # Ensure it is a provisioning NIC that is being deleted dbInstallerNic: Nic = None for dbInstallerNic in dbNode.hardwareprofile.nics: if dbInstallerNic.networkdevice.name == self.getArgs().nic: break else: raise NicNotFound('NIC [%s] is not a provisioning NIC' % (self.getArgs().nic)) hardwareProfiles = [ entry.hardwareprofile for entry in dbInstallerNic.network.hardwareprofilenetworks if entry.hardwareprofile != dbNode.hardwareprofile ] if hardwareProfiles: raise Exception('Hardware profile(s) are associated with this' ' provisioning NIC: [%s]' % (' '.join([hp.name for hp in hardwareProfiles]))) session.query( HardwareProfileNetwork).filter( HardwareProfileNetwork.network == dbInstallerNic.network).\ delete() session.query(HardwareProfileProvisioningNic).filter( HardwareProfileProvisioningNic.nic == dbInstallerNic).delete() dbNetworkId = dbInstallerNic.network.id networkDeviceId = dbInstallerNic.networkdevice.id session.delete(dbInstallerNic) session.query(Network).filter(Network.id == dbNetworkId).delete() self._deleteNetworkDevice(session, networkDeviceId) session.commit() bUpdated = self._updateNetworkConfig(session, dbNode) if bUpdated and self.getArgs().bSync: print('Applying changes to Tortuga...') cmd = 'puppet agent --onetime --no-daemonize >/dev/null 2>&1' tortugaSubprocess.executeCommandAndIgnoreFailure(cmd)
def getPXEReinstallSnippet( self, ksurl: str, node: Node, hardwareprofile: Optional[HardwareProfile] = None, softwareprofile: Optional[SoftwareProfile] = None) \ -> str: # pylint: disable=no-self-use """ Raises: NicNotFound """ # General kickstart/kernel parameters # Find the first nic marked as bootable nic = get_provisioning_nic(node.nics) if nic is None: raise NicNotFound( 'Node [%s] does not have a bootable NIC' % (node.name)) if hardwareprofile is None: hardwareprofile = node.hardwareprofile if softwareprofile is None: softwareprofile = node.softwareprofile # Use settings from software profile, if defined, otherwise use # settings from hardware profile. bootParams = getBootParameters(hardwareprofile, softwareprofile) kernel = bootParams['kernel'] kernelParams = bootParams['kernelParams'] initrd = bootParams['initrd'] bootargs = [ ] if softwareprofile.os.family.version == '7': # RHEL 7.x bootargs.append( 'inst.ks=%s ip=%s:dhcp' % (ksurl, nic.networkdevice.name)) else: # RHEL 6.x bootargs.append('ks=%s' % (ksurl)) bootargs.append('ksdevice=%s' % (nic.networkdevice.name)) # Append kernel parameters, if defined. if kernelParams: bootargs.append(kernelParams) result = '''\ kernel %s append initrd=%s %s''' % (kernel, initrd, ' '.join(bootargs)) return result
def getNicById(self, session, _id): """ Return nic. """ self.getLogger().debug('Retrieving NIC ID [%s]' % _id) dbNic = session.query(Nic).get(_id) if not dbNic: raise NicNotFound('NIC ID [%s] not found.' % (_id)) return dbNic
def getNic(self, session, mac): """ Return nic. This method should be named 'getNicByMAC()' """ self.getLogger().debug('Retrieving NIC with MAC address [%s]' % (mac)) try: return session.query(Nic).filter(Nic.mac == mac).one() except NoResultFound: raise NicNotFound('NIC with MAC address [%s] not found.' % (mac))
def _get_installer_ip(self, network_id): """ Return IP address of provisioning interface on installer :raises NicNotFound: """ prov_nics = self._get_provisioning_nics(self._installer_node) for prov_nic in prov_nics: if prov_nic.getNetwork().getId() == network_id: return ipaddress.IPv4Address(prov_nic.getIp()) raise NicNotFound( 'Network has no corresponding provisioning NIC on installer')
def getPXEReinstallSnippet(self, ksurl, node, hardwareprofile=None, softwareprofile=None): \ # pylint: disable=no-self-use # General kickstart/kernel parameters # Find the first nic marked as bootable nics = [nic for nic in node.nics if nic.boot] if not nics: raise NicNotFound( 'Node [%s] does not have a bootable NIC' % (node.name)) # Choose the first one nic = nics[0] if hardwareprofile is None: hardwareprofile = node.hardwareprofile if softwareprofile is None: softwareprofile = node.softwareprofile # Use settings from software profile, if defined, otherwise use # settings from hardware profile. bootParams = getBootParameters(hardwareprofile, softwareprofile) kernel = bootParams['kernel'] kernelParams = bootParams['kernelParams'] initrd = bootParams['initrd'] bootargs = [ ] if softwareprofile.os.family.version == '7': # RHEL 7.x bootargs.append('inst.ks=%s' % (ksurl)) else: # RHEL 5.x and 6.x bootargs.append('ks=%s' % (ksurl)) bootargs.append('ksdevice=%s' % (nic.networkdevice.name)) # Append kernel parameters, if defined. if kernelParams: bootargs.append(kernelParams) result = '''\ kernel %s append initrd=%s %s''' % (kernel, initrd, ' '.join(bootargs)) return result
def __validate_node(self, node): \ # pylint: disable=no-self-use """ Raises: NodeNotFound NicNotFound """ if not node.name: raise NodeNotFound('Node must have a name') if not node.nics: raise NicNotFound('Node [%s] has no associated nics' % ( node.name))
def __findNicForProvisioningNetwork(self, nics, prov_network): """ TODO: move this elsewhere Raises: NicNotFound """ nics = [nic for nic in nics if nic.network == prov_network] if not nics: raise NicNotFound( 'Unable to find NIC on provisioning network [%s]' % (prov_network.address + '/' + prov_network.netmask)) return nics[0]
def get_provisioning_nic(node): """ Raises: NicNotFound """ # Iterate over all nics associated with node, return first nic # marked as a provisioning nic or first nic without an assigned # ip address. prov_nics = get_provisioning_nics(node) if not prov_nics: raise NicNotFound( 'Node [%s] does not have a provisioning NIC' % (node.name)) return prov_nics[0]
def __populateHardwareProfile(self, session, hardwareProfile, dbHardwareProfile=None): """ Helper function for creating / updating HardwareProfiles. If 'dbHardwareProfile' is specified, this is an update (vs. add) operation Raises: NicNotFound """ # Preload provisioning nics and networks prov_nics = self.__get_provisioning_nics(session) all_networks = self.__get_all_networks(session) networkdevices = self.__get_network_devices(session) # Validate hw profile if hardwareProfile.getName() is None: raise ConfigurationError('Hardware profile requires name.') if hardwareProfile.getNameFormat() is None: raise ConfigurationError( 'Hardware profile requires name format field.') # Handle the special case of a hardware profile not having an # associated idle software profile (ie. Installer hardware # profile) idleSoftwareProfileId = hardwareProfile.getIdleSoftwareProfileId() \ if hardwareProfile.getIdleSoftwareProfileId else None if dbHardwareProfile is None: dbHardwareProfile = HardwareProfiles() dbHardwareProfile.name = hardwareProfile.getName() dbHardwareProfile.description = hardwareProfile.getDescription() dbHardwareProfile.nameFormat = hardwareProfile.getNameFormat() if hardwareProfile.getInstallType() is None: if hardwareProfile.getLocation() == 'remote': dbHardwareProfile.installType = 'bootstrap' else: raise ConfigurationError( 'Hardware profile must have valid install type.') else: dbHardwareProfile.installType = hardwareProfile.\ getInstallType() if hardwareProfile.getLocation() != 'remote': dbHardwareProfile.kernel = hardwareProfile.getKernel() dbHardwareProfile.kernelParams = hardwareProfile.\ getKernelParams() dbHardwareProfile.initrd = hardwareProfile.getInitrd() dbHardwareProfile.localBootParams = hardwareProfile.\ getLocalBootParams() dbHardwareProfile.softwareOverrideAllowed = hardwareProfile.\ getSoftwareOverrideAllowed() dbHardwareProfile.idleSoftwareProfileId = idleSoftwareProfileId dbHardwareProfile.location = hardwareProfile.getLocation() dbHardwareProfile.hypervisorSoftwareProfileId = hardwareProfile.\ getHypervisorSoftwareProfileId() dbHardwareProfile.maxUnits = hardwareProfile.getMaxUnits() dbHardwareProfile.bcastEnabled = hardwareProfile.getBcastEnabled() dbHardwareProfile.mcastEnabled = hardwareProfile.getMcastEnabled() dbHardwareProfile.cost = hardwareProfile.getCost() # Add resource adapter resourceAdapter = hardwareProfile.getResourceAdapter() if resourceAdapter: dbHardwareProfile.resourceAdapter = self.\ _resourceAdaptersDbHandler.getResourceAdapter( session, resourceAdapter.getName()) dbHardwareProfile.resourceAdapterId = dbHardwareProfile.\ resourceAdapter.id # Add networks networks = [] for network in hardwareProfile.getNetworks(): for prov_network in all_networks: if prov_network.address == network.getAddress(): dbNetwork = prov_network break else: raise NetworkNotFound('Network [%s] does not exist' % (network.getAddress())) # Lookup network device for network_device in networkdevices: if network.getNetworkDevice().getName() == network_device.name: dbNetworkDevice = network_device break else: dbNetworkDevice = NetworkDevices() dbNetworkDevice.name = network.getNetworkDevice().getName() # Now check if we have this one already... for dbHardwareProfileNetwork in dbHardwareProfile.\ hardwareprofilenetworks: if dbHardwareProfileNetwork.\ networkDeviceId == dbNetworkDevice.id and \ dbHardwareProfileNetwork.networkId == dbNetwork.id: break else: dbHardwareProfileNetwork = HardwareProfileNetworks() if dbNetwork.id is not None: dbHardwareProfileNetwork.networkId = dbNetwork.id else: dbHardwareProfileNetwork.network = dbNetwork dbHardwareProfileNetwork.hardwareProfileId = \ dbHardwareProfile.id if dbNetworkDevice.id is not None: dbHardwareProfileNetwork.networkDeviceId = \ dbNetworkDevice.id else: dbHardwareProfileNetwork.networkdevice = dbNetworkDevice dbHardwareProfile.hardwareprofilenetworks.append( dbHardwareProfileNetwork) networks.append(dbHardwareProfileNetwork) # Now remove all old networks for dbNetwork in dbHardwareProfile.hardwareprofilenetworks: for network in networks: if network.networkDeviceId == dbNetwork.networkDeviceId \ and network.networkId == dbNetwork.networkId: # Its a keeper break else: # No match...delete time session.delete(dbNetwork) # Add provisioning Nics if hardwareProfile.getProvisioningNics(): # Only one provisioning nic is possible nic = hardwareProfile.getProvisioningNics()[0] for prov_nic in prov_nics: if nic.getIp() == prov_nic.ip: dbNic = prov_nic break else: raise NicNotFound('Provisioning NIC with IP [%s] not found' % (nic.getIp())) if dbNic not in dbHardwareProfile.nics: dbHardwareProfile.nics.append(dbNic) return dbHardwareProfile
def _initializeNics(self, session: Session, dbNode: Node, dbHardwareProfile: HardwareProfile, nic_defs: List[dict], bValidateIp: bool = True, bGenerateIp: bool = True) -> List[Nic]: """ Return list of Nic objects reflecting the configuration of dbNode and nic definitions provided in nic_defs. :raises NetaNotFound: :raises InvalidMacAddress: :raises MacAddressAlreadyExists: """ nics = [] hwpnetworks = dbHardwareProfile.hardwareprofilenetworks[:] hwpnetworks.sort(key=lambda a: a.networkdevice.name) for nic_def, dbHardwareProfileNetwork in itertools.zip_longest( nic_defs, hwpnetworks, fillvalue=None): # Create a nic for each associated hardware profile network dbNic = Nic() dbNic.node = dbNode if nic_def and 'mac' in nic_def: # # MAC addresses are generated for virtualization platforms # such as libvirt and VMware # dbNic.mac = self._validate_mac_address( session, nic_def['mac'], dbHardwareProfileNetwork.network) # # Validate IP, if specified, otherwise generate an IP, if # requested # if nic_def and 'ip' in nic_def: if bValidateIp: self._validate_ip_address(nic_def['ip'], dbHardwareProfileNetwork.network) dbNic.ip = nic_def['ip'] else: if dbHardwareProfile.location == 'local' and \ not dbHardwareProfileNetwork: raise NicNotFound( 'Hardware profile [%s] does not have a provisioning' ' network' % (dbHardwareProfile.name)) if bGenerateIp and \ dbHardwareProfileNetwork.network.type == 'provision': # Generate an IP address for the specified nic dbNic.ip = self.generate_provisioning_ip_address( dbHardwareProfileNetwork.network) self._logger.debug('Generated IP [%s] for node [%s]' % (dbNic.ip, dbNode.name)) if dbNic.ip or \ dbHardwareProfileNetwork and \ dbHardwareProfileNetwork.network.type != 'provision': # Only add a network and network device for nodes that have # managed IP addresses. if dbHardwareProfileNetwork: dbNic.network = dbHardwareProfileNetwork.network dbNic.networkdevice = \ dbHardwareProfileNetwork.networkdevice # Set the 'boot' flag if this is a provisioning network dbNic.boot = dbNic.network and dbNic.network.type == 'provision' if dbNic.ip: reservedIps.append(dbNic.ip) nics.append(dbNic) return nics
def __populateHardwareProfile( self, session: Session, hardwareProfile: HardwareProfile, dbHardwareProfile: Optional[HardwareProfileModel] = None) \ -> HardwareProfileModel: """ Helper function for creating / updating hardware profiles. If 'dbHardwareProfile' is specified, this is an update (vs. add) operation Raises: NicNotFound ResourceAdapterNotFound InvalidArgument ConfigurationError """ # Preload provisioning nics and networks prov_nics = self.__get_provisioning_nics(session) all_networks = self.__get_all_networks(session) # Validate hw profile if hardwareProfile.getName() is None: raise ConfigurationError('Hardware profile requires name.') if hardwareProfile.getNameFormat() is None: raise ConfigurationError( 'Hardware profile requires name format field.') if dbHardwareProfile is None: dbHardwareProfile = HardwareProfileModel() dbHardwareProfile.name = hardwareProfile.getName() dbHardwareProfile.description = hardwareProfile.getDescription() dbHardwareProfile.nameFormat = hardwareProfile.getNameFormat() if hardwareProfile.getInstallType() is None: if hardwareProfile.getLocation() == 'remote': dbHardwareProfile.installType = 'bootstrap' else: dbHardwareProfile.installType = 'package' else: dbHardwareProfile.installType = hardwareProfile.\ getInstallType() if hardwareProfile.getLocation() != 'remote': dbHardwareProfile.kernel = hardwareProfile.getKernel() dbHardwareProfile.kernelParams = \ hardwareProfile.getKernelParams() dbHardwareProfile.initrd = hardwareProfile.getInitrd() dbHardwareProfile.localBootParams = \ hardwareProfile.getLocalBootParams() dbHardwareProfile.softwareOverrideAllowed = hardwareProfile.\ getSoftwareOverrideAllowed() dbHardwareProfile.location = hardwareProfile.getLocation() dbHardwareProfile.cost = hardwareProfile.getCost() # Add resource adapter resource_adapter_name = \ hardwareProfile.getResourceAdapter().getName() \ if hardwareProfile.getResourceAdapter() else 'default' dbHardwareProfile.resourceadapter = \ self._resourceAdaptersDbHandler.getResourceAdapter( session, resource_adapter_name) if hardwareProfile.getDefaultResourceAdapterConfig(): adapter_cfg = None self._logger.debug( 'Setting default resource adapter config: {}'.format( hardwareProfile.getDefaultResourceAdapterConfig()) ) for adapter_cfg in \ dbHardwareProfile.resourceadapter.resource_adapter_config: if adapter_cfg.name == \ hardwareProfile.getDefaultResourceAdapterConfig(): break else: raise InvalidArgument( 'Resource adapter configuration profile [{}] is' ' invalid'.format( hardwareProfile.getDefaultResourceAdapterConfig()) ) dbHardwareProfile.default_resource_adapter_config = adapter_cfg else: dbHardwareProfile.default_resource_adapter_config = None # Add networks networks = [] for network in hardwareProfile.getNetworks(): for prov_network in all_networks: if prov_network.address == network.getAddress(): dbNetwork = prov_network break else: raise NetworkNotFound( 'Network [%s] does not exist' % (network.getAddress())) dbNetworkDevice = \ self._networkDevicesDbHandler.createNetworkDeviceIfNotExists( session, network.getNetworkDevice().getName()) # Now check if we have this one already... for dbHardwareProfileNetwork in \ dbHardwareProfile.hardwareprofilenetworks: if dbHardwareProfileNetwork.networkDeviceId == \ dbNetworkDevice.id and \ dbHardwareProfileNetwork.networkId == dbNetwork.id: break else: dbHardwareProfileNetwork = HardwareProfileNetwork() dbHardwareProfileNetwork.hardwareprofile = dbHardwareProfile if dbNetwork.id is not None: dbHardwareProfileNetwork.networkId = dbNetwork.id else: dbHardwareProfileNetwork.network = dbNetwork dbHardwareProfileNetwork.hardwareProfileId = \ dbHardwareProfile.id if dbNetworkDevice.id is not None: dbHardwareProfileNetwork.networkDeviceId = \ dbNetworkDevice.id else: dbHardwareProfileNetwork.networkdevice = dbNetworkDevice dbHardwareProfile.hardwareprofilenetworks.append( dbHardwareProfileNetwork) networks.append(dbHardwareProfileNetwork) # Now remove all old networks for dbNetwork in dbHardwareProfile.hardwareprofilenetworks: for network in networks: if network.networkDeviceId == dbNetwork.networkDeviceId \ and network.networkId == dbNetwork.networkId: # Its a keeper break else: # No match...delete time session.delete(dbNetwork) # Add provisioning Nics if hardwareProfile.getProvisioningNics(): # Only one provisioning nic is possible nic = hardwareProfile.getProvisioningNics()[0] for prov_nic in prov_nics: if nic.getIp() == prov_nic.ip: dbNic = prov_nic break else: raise NicNotFound( 'Provisioning NIC with IP [%s] not found' % nic.getIp()) if dbNic not in dbHardwareProfile.nics: dbHardwareProfile.nics.append(dbNic) return dbHardwareProfile