示例#1
0
    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'
        ]
示例#2
0
    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()
示例#3
0
    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
示例#4
0
    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)
示例#5
0
    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
示例#6
0
    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
示例#7
0
    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))
示例#8
0
    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')
示例#9
0
    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
示例#10
0
    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))
示例#11
0
    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]
示例#12
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]
示例#13
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
示例#14
0
    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
示例#15
0
    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