Beispiel #1
0
    def addSoftwareProfile(self, softwareProfile, session=None):
        """
        Insert software profile into the db.

        Raises:
            SoftwareProfileAlreadyExists
            DbError
        """

        # Keep local 'session' instance.  If 'session' is None,
        # ensure transaction is committed before returning to the
        # caller, otherwise the caller is responsible.  On exceptions,
        # the rollback is performed regardless.
        _session = session

        if _session is None:
            _session = DbManager().openSession()

        try:
            try:
                dbSoftwareProfile = self._softwareProfilesDbHandler.\
                    getSoftwareProfile(
                        _session, softwareProfile.getName())

                raise SoftwareProfileAlreadyExists(
                    'Software profile [%s] already exists' % (softwareProfile))
            except SoftwareProfileNotFound as ex:
                pass

            dbSoftwareProfile = self.__populateSoftwareProfile(
                _session, softwareProfile)

            _session.query(func.max(SoftwareProfiles.id)).one()

            softwareProfile.setId(dbSoftwareProfile.id)

            if session is None:
                _session.commit()

            self.getLogger().info('Added software profile [%s]' %
                                  (dbSoftwareProfile.name))

            return dbSoftwareProfile
        except TortugaException as ex:
            _session.rollback()
            raise
        except Exception as ex:
            _session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            if session is None:
                DbManager().closeSession()
Beispiel #2
0
def validate_addnodes_request(addNodesRequest):
    """
    Raises:
        HardwareProfileNotFound
        SoftwareProfileNotFound
        ProfileMappingNotAllowed
        InvalidArgument
    """

    if 'hardwareProfile' not in addNodesRequest and \
            'softwareProfile' not in addNodesRequest:
        raise InvalidArgument(
            'Hardware and/or software profile must be specified')

    hpapi = HardwareProfilesDbHandler()
    spapi = SoftwareProfilesDbHandler()

    hardwareProfileName = addNodesRequest['hardwareProfile'] \
        if 'hardwareProfile' in addNodesRequest else None
    nodeDetails = addNodesRequest.get('nodeDetails', [])
    softwareProfileName = addNodesRequest['softwareProfile'] \
        if 'softwareProfile' in addNodesRequest else None
    nodeCount = int(addNodesRequest.get('count', 0))
    rackNumber = addNodesRequest.get('rack')

    session = DbManager().openSession()

    try:
        # Look up hardware profile
        hp = hpapi.getHardwareProfile(session, hardwareProfileName) \
            if hardwareProfileName else None

        # Look up software profile
        sp = spapi.getSoftwareProfile(
            session, softwareProfileName) if softwareProfileName else None

        if sp and not sp.isIdle and 'isIdle' in addNodesRequest and \
                addNodesRequest['isIdle']:
            raise InvalidArgument(
                'Software profile [%s] is not idle software profile' %
                (softwareProfileName))

        # Make sure that if a software profile is given that it is allowed
        # to be used with the given hardware profile
        if sp is not None and hp is not None:
            checkProfilesMapped(sp, hp)
        elif sp is not None and hp is None:
            if not sp.hardwareprofiles:
                raise InvalidArgument(
                    'Software profile [{0}] is not mapped to any hardware'
                    ' profiles'.format(softwareProfileName))

            if len(sp.hardwareprofiles) > 1:
                raise InvalidArgument(
                    'Ambiguous request: multiple hardware profiles are'
                    ' mapped to software profile [{0}]'.format(
                        softwareProfileName))

            hp = sp.hardwareprofiles[0]
        elif hp is not None and sp is None and not addNodesRequest['isIdle']:
            if not hp.mappedsoftwareprofiles:
                raise InvalidArgument(
                    'Hardware profile [{0}] is not mapped to any software'
                    ' profiles'.format(hardwareProfileName))

            if len(hp.mappedsoftwareprofiles) > 1:
                raise InvalidArgument(
                    'Ambiguous request: multiple software profiles are'
                    ' mapped to hardware profile [{0}]'.format(
                        hardwareProfileName))

            sp = hp.mappedsoftwareprofiles[0]

        # Ensure user does not make a request for DHCP discovery mode.
        # Currently, this is determined by the presence of the item
        # 'nodeDetails' in addNodesRequest. Ultimately, this should be
        # shared code between here and the default resource adapter.
        if hp.resourceadapter and \
                hp.resourceadapter.name == 'default' and not nodeDetails:
            raise InvalidArgument(
                'DHCP discovery is not available through WS API.')

        if sp and 'softwareProfile' not in addNodesRequest:
            addNodesRequest['softwareProfile'] = sp.name

        if 'hardwareProfile' not in addNodesRequest:
            addNodesRequest['hardwareProfile'] = hp.name

        # Validate 'nodeDetails'

        if nodeDetails:
            # Reconcile nodeDetails that contain hostnames with hwp name
            # format
            bWildcardNameFormat = hp.nameFormat == '*'
            hostname = nodeDetails[0]['name'] \
                if 'name' in nodeDetails[0] else None
            if hostname and not bWildcardNameFormat:
                # Host name specified, but hardware profile does not
                # allow setting the host name
                raise InvalidArgument('Hardware profile does not allow setting'
                                      ' host names of imported nodes')
            elif not hostname and bWildcardNameFormat:
                # Host name not specified but hardware profile expects it
                raise InvalidArgument('Hardware profile requires imported node'
                                      ' name to be set')

            if nodeCount > 0 and nodeCount != len(nodeDetails):
                raise InvalidArgument('Node count must be equal to number'
                                      ' of MAC/IP/node names provided')

            if hostname:
                # Ensure host does not already exist
                existing_node = session.query(Nodes).filter(
                    Nodes.name == hostname).first()
                if existing_node:
                    raise NodeAlreadyExists('Node [%s] already exists' %
                                            (hostname))

        # Prohibit running add-host against installer
        validate_hwprofile(hp)

        # If the given hardwareProfile's nameFormat contains "#R',
        # then the rackNumber is required.
        nameFormat = hp.nameFormat

        if nameFormat.find('#R') != -1 and rackNumber is None:
            raise InvalidArgument(
                'Missing "rackNumber" for name format [%s] of'
                ' hardware profile [%s]' % (nameFormat, hp))
        adapter = resourceAdapterFactory.getApi(hp.resourceadapter.name)

        adapter.validate_start_arguments(addNodesRequest,
                                         hp,
                                         dbSoftwareProfile=sp)
    finally:
        DbManager().closeSession()