Esempio n. 1
0
    def __init__(self):
        TortugaDbApi.__init__(self)

        self._hardwareProfilesDbHandler = HardwareProfilesDbHandler()
        self._nodesDbHandler = NodesDbHandler()
        self._globalParametersDbHandler = GlobalParametersDbHandler()
        self._adminsDbHandler = AdminsDbHandler()
        self._nicsDbHandler = NicsDbHandler()
        self._resourceAdaptersDbHandler = ResourceAdaptersDbHandler()
        self._networkDevicesDbHandler = NetworkDevicesDbHandler()
        self._networksDbHandler = NetworksDbHandler()
Esempio n. 2
0
    def __init__(self):
        TortugaDbObjectHandler.__init__(self)

        self._nicsDbHandler = NicsDbHandler()
        self._hardwareProfilesDbHandler = HardwareProfilesDbHandler()
        self._softwareProfilesDbHandler = SoftwareProfilesDbHandler()
        self._softwareUsesHardwareDbHandler = SoftwareUsesHardwareDbHandler()
        self._globalParametersDbHandler = GlobalParametersDbHandler()
Esempio n. 3
0
    def test_getHardwareProfileList_tag2(self):
        # 'tag2' returns hardware profile 'profile2' only
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags=[(self.tags[1].name, )])

        assert result

        assert len(result) == 1

        assert self.tags[1] in result[0].tags
Esempio n. 4
0
    def test_getHardwareProfileList_tag1_and_tag2(self):
        # 'tag1' and 'tag2' returns both profiles
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags={
                'tag1': None,
                'tag2': None
            })

        assert result and len(result) == 2 and \
            result[0].name == 'profile1' and result[1].name == 'profile2'
Esempio n. 5
0
    def test_getHardwareProfile_resource_adapter_config(self):
        result = HardwareProfilesDbHandler().getHardwareProfile(
            self.session, 'aws2')

        assert result.default_resource_adapter_config and \
            result.default_resource_adapter_config.name != 'default'

        assert result.default_resource_adapter_config.resourceadapter == \
            result.resourceadapter

        assert result.default_resource_adapter_config.name == 'nondefault'
Esempio n. 6
0
    def test_getHardwareProfileList_tag1_and_tag2(self):
        # 'tag1' and 'tag2' returns both profiles
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags=[(self.tags[0].name, ), (self.tags[1].name, )])

        assert result

        assert len(result) == 2

        assert self.hardwareprofiles[0] in result
        assert self.hardwareprofiles[1] in result
Esempio n. 7
0
def test_start(load_config_dict_mock, pre_add_host_mock,
               fire_provisioned_even_mock, get_instance_size_mapping_mock,
               dbm, valid_ami):
    """
    Test ResourceAdapter.start() workflow
    """

    get_instance_size_mapping_mock.return_value = 8

    load_config_dict_mock.return_value = {
        'awsaccesskey': 'the_key',
        'awssecretkey': 'the_secret',
        'keypair': 'the_keypair',
        'ami': valid_ami,
        'use_instance_hostname': 'true',
        'instancetype': 'the_instancetype'
    }

    with dbm.session() as session:
        adapter = Aws(addHostSession='123EXAMPLE')

        # override default sleep time
        adapter.LAUNCH_INITIAL_SLEEP_TIME = 0.0

        hardwareprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'aws2'
        )

        softwareprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute'
        )

        addNodesRequest = {
            'count': 2,
            'hardwareProfile': hardwareprofile.name,
            'softwareProfile': softwareprofile.name,
        }

        nodes = adapter.start(
            addNodesRequest, session, hardwareprofile,
            dbSoftwareProfile=softwareprofile
        )

        assert nodes and isinstance(nodes, list) and \
            isinstance(nodes[0], Node)

        assert nodes[0].instance.instance

        if len(nodes) > 1:
            assert nodes[1].instance.instance

    pre_add_host_mock.assert_called()

    fire_provisioned_even_mock.assert_called()
Esempio n. 8
0
    def __init__(self):
        TortugaDbApi.__init__(self)

        from tortuga.db.hardwareProfilesDbHandler \
            import HardwareProfilesDbHandler
        self._hardwareProfilesDbHandler = HardwareProfilesDbHandler()
        from tortuga.db.nodesDbHandler import NodesDbHandler
        from tortuga.db.nicsDbHandler import NicsDbHandler
        from tortuga.db.networksDbHandler import NetworksDbHandler
        self._nodesDbHandler = NodesDbHandler()
        self._nicsDbHandler = NicsDbHandler()
        self._networksDbHandler = NetworksDbHandler()
def test_failed_initializeNode(dbm):
    with dbm.session() as session:
        hardware_profile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'nonetwork')

        software_profile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')

        node = Node()

        with pytest.raises(NetworkNotFound):
            api.initializeNode(session, node, hardware_profile,
                               software_profile, [])
Esempio n. 10
0
def test_validate_start_arguments(os_obj_factory_mock, dbm):
    with dbm.session() as session:
        swprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')
        hwprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'localiron')

        adapter = Default()
        adapter.session = session

        addNodesRequest = {}

        # all 'default' nodes must have a 'nodeDetails' attribute in
        # addNodesRequest
        with pytest.raises(CommandFailed):
            adapter.validate_start_arguments(addNodesRequest, hwprofile,
                                             swprofile)
Esempio n. 11
0
def test_invalid_host_name_request(os_obj_factory_mock, dbm):
    """
    CommandFailed exception should be raised if attempting to add node to
    hardware profile with name format set to "*" and without specifying a
    host name.
    """

    with dbm.session() as session:
        swprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')
        hwprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'localironalt')

        adapter = Default()
        adapter.session = session

        with pytest.raises(CommandFailed):
            adapter.validate_start_arguments({}, hwprofile, swprofile)
Esempio n. 12
0
def test_duplicate_host_name(os_obj_factory_mock, dbm):
    with dbm.session() as session:
        swprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')
        hwprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'localiron')

        adapter = Default()
        adapter.session = session

        addNodesRequest = {
            'nodeDetails': [{
                'name': 'compute-01.private',
            }],
        }

        with pytest.raises(NodeAlreadyExists):
            adapter.validate_start_arguments(addNodesRequest, hwprofile,
                                             swprofile)
def test_initializeNode(dbm):
    with dbm.session() as session:
        hardware_profile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'localiron')

        software_profile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')

        node = Node()

        nic_defs = [{
            'mac': '00:00:00:00:00:01',
        }]

        api.initializeNode(session, node, hardware_profile, software_profile,
                           nic_defs)

        assert node.name
        assert node.nics and len(node.nics) == 1 and \
            node.nics[0].mac == '00:00:00:00:00:01' and \
            node.nics[0].boot
Esempio n. 14
0
def main():
    gce = Gce()

    session = DbManager().openSession()

    # Find first hardware profile that has 'gce' as the resource adapter
    for hwprofile in \
            HardwareProfilesDbHandler().getHardwareProfileList(session):
        if hwprofile.resourceadapter and \
           hwprofile.resourceadapter.name == 'gce':
            break
    else:
        raise Exception(
            'No hardware profile found with Google Compute Engine resource'
            ' adapter enabled')

    print(('Using hardware profile \'%s\''
           ' (use --hardware-profile to override)' % (hwprofile.name)))

    # Find first software profile mapped to hardware profile
    swprofile = hwprofile.mappedsoftwareprofiles[0]

    print(('Using software profile \'%s\''
           ' (use --software-profile to override)' % (swprofile.name)))

    gce_session = gce._Gce__initSession(hwprofile)

    # gce._Gce__launchInstance(gce_session, instance_name)

    addNodesRequest = {
        'count': 1,
        # 'nodeDetails': [
        #     {
        #         'name': 'compute-05.private',
        #     },
        # ],
    }

    gce._Gce__addActiveNodes(
        gce_session, session, addNodesRequest, hwprofile, swprofile)
Esempio n. 15
0
def test_valid_host_name_request(os_obj_factory_mock, dbm):
    with dbm.session() as session:
        swprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute')
        hwprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'localironalt')

        adapter = Default()
        adapter.session = session

        addNodesRequest = {
            'nodeDetails': [{
                'name': 'myfakename',
                'nics': [
                    {
                        'mac': '00:00:00:00:00:01',
                    },
                ]
            }]
        }

        adapter.validate_start_arguments(addNodesRequest, hwprofile, swprofile)
Esempio n. 16
0
def worker_thread(thread_id):
    print('Starting thread {}'.format(thread_id))

    db_session = dbm.openSession()

    dbSoftwareProfile = SoftwareProfilesDbHandler().getSoftwareProfile(
        db_session, 'execd')
    dbHardwareProfile = HardwareProfilesDbHandler().getHardwareProfile(
        db_session, 'openstack')

    adapter = Openstack()

    configDict = adapter.getResourceAdapterConfig('openstack')

    session = adapter._Openstack__initSession(configDict,
                                              swProfile=dbSoftwareProfile,
                                              hwProfile=dbHardwareProfile)

    print('Currently allocated floating IPs: [{0}]'.format(' '.join([
        floating_ip['ip']
        for floating_ip in adapter._get_allocated_floating_ips(session)
    ])))

    while True:
        item = queue.get()

        try:
            print('Thread {} requesting {} floating ips'.format(
                thread_id, item))

            floating_ips = adapter._get_floating_ips(session, item)

            floating_ips = floating_ips[0] + floating_ips[1]

            print('Got: {}'.format(' '.join(
                [floating_ip['ip'] for floating_ip in floating_ips])))
            # print 'Got: {}'.format(floating_ips)
        finally:
            queue.task_done()
Esempio n. 17
0
    def addHosts(self, session, addHostSession, addHostRequest):
        """
        Raises:
            HardwareProfileNotFound
        """

        self.getLogger().debug('addHosts()')

        softwareProfilesDbHandler = SoftwareProfilesDbHandler()
        hardwareProfilesDbHandler = HardwareProfilesDbHandler()

        dbHardwareProfile = hardwareProfilesDbHandler.getHardwareProfile(
            session, addHostRequest['hardwareProfile'])

        if not dbHardwareProfile.resourceadapter:
            errmsg = ('Resource adapter not defined for hardware'
                      ' profile [%s]' % (dbHardwareProfile.name))

            self.getLogger().error(errmsg)

            raise ResourceAdapterNotFound(errmsg)

        softwareProfileName = addHostRequest['softwareProfile'] \
            if 'softwareProfile' in addHostRequest else None

        dbSoftwareProfile = softwareProfilesDbHandler.\
            getSoftwareProfile(session, softwareProfileName) \
            if softwareProfileName else None

        # Look up and/or create tags as necessary
        tags = get_tags(session, addHostRequest['tags']) \
            if 'tags' in addHostRequest else []

        ResourceAdapterClass = resourceAdapterFactory.getResourceAdapterClass(
            dbHardwareProfile.resourceadapter.name)

        resourceAdapter = ResourceAdapterClass(addHostSession=addHostSession)

        # Call the start() method of the resource adapter
        newNodes = resourceAdapter.start(addHostRequest,
                                         session,
                                         dbHardwareProfile,
                                         dbSoftwareProfile=dbSoftwareProfile)

        # Apply tags to new nodes
        for node in newNodes:
            node.tags = tags

        # Commit new node(s) to database
        session.commit()

        # Only perform post-add operations if we actually added a node
        if newNodes:
            if dbSoftwareProfile and not dbSoftwareProfile.isIdle:
                self.getLogger().info(
                    'Node(s) added to software profile [%s] and'
                    ' hardware profile [%s]' %
                    (dbSoftwareProfile.name if dbSoftwareProfile else 'None',
                     dbHardwareProfile.name))

                newNodeNames = [tmpNode.name for tmpNode in newNodes]

                resourceAdapter.hookAction('add', newNodeNames)

                self.postAddHost(dbHardwareProfile.name, softwareProfileName,
                                 addHostSession)

                resourceAdapter.hookAction('start', newNodeNames)

        self.getLogger().debug('Add host workflow complete')
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tortuga.db.dbManager import DbManager
from tortuga.db.hardwareProfilesDbHandler import HardwareProfilesDbHandler
from tortuga.db.softwareProfilesDbHandler import SoftwareProfilesDbHandler

from tortuga.node import nodeApiFactory

dbSession = DbManager().openSession()

dbHardwareProfile = HardwareProfilesDbHandler().getHardwareProfile(
    dbSession, 'vmware3')

dbSoftwareProfile = SoftwareProfilesDbHandler().getSoftwareProfile(
    dbSession, 'BasicCompute')

addNodeRequest = {
    'name': 'compute-1.isurfer.ca',
    'nics': [
        {
            'device': 0,
            'ip': '192.168.1.129',
        },
    ]
}

node_api = nodeApiFactory.getNodeApi()
Esempio n. 19
0
def test_start_update_node(load_config_dict_mock, pre_add_host_mock,
                           fire_provisioned_event_mock, dbm, valid_ami):
    configDict = {
        'awsaccesskey': 'the_key',
        'awssecretkey': 'the_secret',
        'ami': valid_ami,
        'use_instance_hostname': 'true',
    }

    load_config_dict_mock.return_value = configDict

    with dbm.session() as session:
        addHostSession = '123EXAMPLE'

        adapter = Aws(addHostSession=addHostSession)

        # override default sleep time
        adapter.LAUNCH_INITIAL_SLEEP_TIME = 0.0

        count = 3

        hardwareprofile = HardwareProfilesDbHandler().getHardwareProfile(
            session, 'aws2'
        )

        softwareprofile = SoftwareProfilesDbHandler().getSoftwareProfile(
            session, 'compute'
        )

        # create instances to be associated with nodes
        conn = boto.connect_ec2(configDict['awsaccesskey'],
                                configDict['awssecretkey'])

        conn.run_instances(
            configDict['ami'],
            min_count=count,
            max_count=count
        )

        # get newly created instances
        instances = conn.get_only_instances()

        # intialize 'addNodesRequest'
        addNodesRequest = {
            'nodeDetails': [],
        }

        for instance in instances:
            addNodesRequest['nodeDetails'].append({
                'name': instance.private_dns_name,
                'metadata': {
                    'ec2_instance_id': instance.id,
                    'ec2_ipaddress': instance.private_ip_address,
                }
            })

        # call Aws.start() with instance metadata
        nodes = adapter.start(
            addNodesRequest, session, hardwareprofile,
            dbSoftwareProfile=softwareprofile
        )

        assert nodes and len(nodes) == count

        assert isinstance(nodes[0], Node)

        assert nodes[0].softwareprofile.name == softwareprofile.name

        assert nodes[0].hardwareprofile.name == hardwareprofile.name

        assert nodes[0].addHostSession == addHostSession

        fire_provisioned_event_mock.assert_called()

        pre_add_host_mock.assert_called()
Esempio n. 20
0
class HardwareProfileDbApi(TortugaDbApi):
    """
    HardwareProfile DB API class.
    """
    def __init__(self):
        TortugaDbApi.__init__(self)

        self._hardwareProfilesDbHandler = HardwareProfilesDbHandler()
        self._nodesDbHandler = NodesDbHandler()
        self._globalParametersDbHandler = GlobalParametersDbHandler()
        self._adminsDbHandler = AdminsDbHandler()
        self._nicsDbHandler = NicsDbHandler()
        self._resourceAdaptersDbHandler = ResourceAdaptersDbHandler()
        self._networkDevicesDbHandler = NetworkDevicesDbHandler()
        self._networksDbHandler = NetworksDbHandler()

    def getHardwareProfile(self,
                           name: str,
                           optionDict: Optional[Union[dict, None]] = None):
        """
        Get hardwareProfile from the db.

            Returns:
                hardwareProfile
            Throws:
                HardwareProfileNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, name)

            self.loadRelations(dbHardwareProfile, optionDict)
            self.loadRelations(dbHardwareProfile, dict(tags=True))

            return HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getHardwareProfileById(self,
                               hardwareProfileId: int,
                               optionDict: Optional[Union[dict, None]] = None):
        """
        Get hardwareProfile from the db.

            Returns:
                hardwareProfile
            Throws:
                HardwareProfileNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfileById(session, hardwareProfileId)

            self.loadRelations(dbHardwareProfile, optionDict)

            return HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getHardwareProfileList(self,
                               optionDict: Optional[Union[dict, None]] = None,
                               tags: Optional[Union[dict, None]] = None):
        """
        Get list of all available hardwareProfiles from the db.

            Returns:
                [hardwareProfile]
            Throws:
                DbError
        """

        session = DbManager().openSession()

        try:
            dbHardwareProfileList = self._hardwareProfilesDbHandler.\
                getHardwareProfileList(session, tags=tags)

            hardwareProfileList = TortugaObjectList()

            for dbHardwareProfile in dbHardwareProfileList:
                # For now expand networks
                self.loadRelation(dbHardwareProfile, 'hardwareprofilenetworks')

                self.loadRelations(dbHardwareProfile, optionDict)

                self.loadRelations(dbHardwareProfile, dict(tags=True))

                hardwareProfileList.append(
                    HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__))

            return hardwareProfileList
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def setIdleSoftwareProfile(self,
                               hardwareProfileName,
                               softwareProfileName=None):
        """
        Sets the idle software profile

        Returns:
            -none-

        Raises:
            SoftwareProfileNotFound
            SoftwareProfileNotIdle
        """

        session = DbManager().openSession()

        try:
            dbSoftwareProfile = SoftwareProfilesDbHandler().\
                getSoftwareProfile(session, softwareProfileName) \
                if softwareProfileName else None

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            self._hardwareProfilesDbHandler.setIdleSoftwareProfile(
                dbHardwareProfile, dbSoftwareProfile)

            session.commit()
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def addHardwareProfile(self, hardwareProfile, session=None):
        """
        Insert hardwareProfile into the db.

            Returns:
                (none)
            Throws:
                HardwareProfileAlreadyExists
                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:
                self._hardwareProfilesDbHandler.getHardwareProfile(
                    _session, hardwareProfile.getName())

                raise HardwareProfileAlreadyExists(
                    'Hardware profile [%s] already exists' % (hardwareProfile))
            except HardwareProfileNotFound as ex:
                pass

            dbHardwareProfile = self.__populateHardwareProfile(
                _session, hardwareProfile)

            _session.add(dbHardwareProfile)

            if session is None:
                _session.commit()

            self.getLogger().info('Added hardware profile [%s]' %
                                  (dbHardwareProfile.name))
        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()

    def deleteHardwareProfile(self, name):
        """
        Delete hardwareProfile from the db.

            Returns:
                None
            Throws:
                HardwareProfileNotFound
                DbError
                TortugaException
        """

        session = DbManager().openSession()

        try:
            hwProfile = self._hardwareProfilesDbHandler.getHardwareProfile(
                session, name)

            if hwProfile.nodes:
                raise TortugaException(
                    'Unable to remove hardware profile with associated'
                    ' nodes')

            # First delete the mappings
            hwProfile.mappedsoftwareprofiles = []

            self.getLogger().debug(
                'Marking hardware profile [%s] for deletion' % (name))

            session.delete(hwProfile)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def copyHardwareProfile(self, srcHardwareProfileName,
                            dstHardwareProfileName):
        session = DbManager().openSession()

        try:
            srcHardwareProfile = self.getHardwareProfile(
                srcHardwareProfileName, {
                    'admins': True,
                    'hardwareprofilenetworks': True,
                    'nics': True,
                    'resourceadapter': True,
                })

            dstHardwareProfile = \
                self.getHardwareProfile(srcHardwareProfileName)

            dstHardwareProfile.setName(dstHardwareProfileName)

            newDescription = 'Copy of %s' % (
                dstHardwareProfile.getDescription())

            dstHardwareProfile.setDescription(newDescription)

            dstHardwareProfile.setNetworks(srcHardwareProfile.getNetworks())

            dstHardwareProfile.setProvisioningNics(
                srcHardwareProfile.getProvisioningNics())

            dstHardwareProfile.setResourceAdapter(
                srcHardwareProfile.getResourceAdapter())

            self.addHardwareProfile(dstHardwareProfile, session)

            session.commit()
        finally:
            DbManager().closeSession()

    def getNode(self, name):
        """
        Get node from the db.

            Returns:
                node
            Throws:
                NodeNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            return self._nodesDbHandler.getNode(session, name)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def deleteNode(self, name):
        """
        Delete node from the db.

            Returns:
                None
            Throws:
                NodeNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            self._nodesDbHandler.deleteNode(session, name)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def addAdmin(self, hardwareProfileName, adminUsername):
        """
        Add an admin to this hardware profile

        Raises:
            AdminAlreadyExists
        """

        session = DbManager().openSession()

        try:
            dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            if dbAdmin in dbHardwareProfile.admins:
                raise AdminAlreadyExists(
                    'The admin %s is already associated with %s.' %
                    (adminUsername, hardwareProfileName))

            dbHardwareProfile.admins.append(dbAdmin)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def deleteAdmin(self, hardwareProfileName, adminUsername):
        """
        Delete an admin from a hardware profile

        Raises:
            AdminNotFound
        """

        session = DbManager().openSession()

        try:
            dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            if dbAdmin not in dbHardwareProfile.admins:
                raise AdminNotFound('Admin user [%s] not associated with %s.' %
                                    (adminUsername, hardwareProfileName))

            dbHardwareProfile.admins.remove(dbAdmin)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def updateHardwareProfile(self, hardwareProfileObject):
        """ Update Hardware Profile Object """

        session = DbManager().openSession()

        try:
            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfileById(session,
                                       hardwareProfileObject.getId())

            self.__populateHardwareProfile(session, hardwareProfileObject,
                                           dbHardwareProfile)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def __getInstallerNode(self, session):
        return self._nodesDbHandler.getNode(session,
                                            ConfigManager().getInstaller())

    def __get_provisioning_nics(self, session):
        return self.__getInstallerNode(session).nics

    def __get_all_networks(self, session):
        return self._networksDbHandler.getNetworkList(session)

    def __get_network_devices(self, session):         \
            # pylint: disable=no-self-use

        return session.query(NetworkDevices).all()

    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 getHypervisorNodes(self, hardwareProfileName):
        """
        Get list of nodes that belong to hypervisorSoftwareProfileId
        assigned to the given hardware profile name.
        """

        session = DbManager().openSession()

        try:
            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            if not dbHardwareProfile.hypervisor:
                return TortugaObjectList()

            return self.getTortugaObjectList(
                Node, dbHardwareProfile.hypervisor.nodes)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def setProvisioningNic(self, hardwareProfileName, nicId):
        session = DbManager().openSession()

        try:
            dbNic = self._nicsDbHandler.getNicById(session, nicId)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            dbHardwareProfile.nics.append(dbNic)

            session.commit()
        except sqlalchemy.exc.IntegrityError as ex:
            # Entry for this hwProfile/nicId already exists, ignore
            self.getLogger().debug(
                'setProvisioningNic(): entry already exists for'
                ' hwProfile=%s, nicId=%d' % (hardwareProfileName, nicId))
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    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()
Esempio n. 21
0
def validate_addnodes_request(session: Session, addNodesRequest: Dict[str,
                                                                      Any]):
    """
    Raises:
        HardwareProfileNotFound
        SoftwareProfileNotFound
        ProfileMappingNotAllowed
        InvalidArgument
        OperationFailed
    """

    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')

    # 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

    # 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:
        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]

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

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

    swprofile_node_count = len(sp.nodes)

    # 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')

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

    # check if software profile is locked
    if sp.lockedState:
        if sp.lockedState == 'HardLocked':
            raise OperationFailed(
                'Nodes cannot be added to hard locked software'
                ' profile [{}]'.format(sp.name))
        elif sp.lockedState == 'SoftLocked':
            if 'force' not in addNodesRequest or \
                    not addNodesRequest['force']:
                raise OperationFailed(
                    'Use --force argument to add nodes to soft locked'
                    f' software profile [{sp.name}]')

    # ensure adding nodes does not exceed imposed limits
    if sp.maxNodes > 0 and \
            (swprofile_node_count + nodeCount) > sp.maxNodes:
        raise OperationFailed(
            'Request to add {} node(s) exceeds software profile'
            ' limit of {} nodes'.format(nodeCount, sp.maxNodes))

    # 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.get_api(hp.resourceadapter.name)
    adapter.session = session

    adapter.validate_start_arguments(addNodesRequest, hp, dbSoftwareProfile=sp)
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pprint
from tortuga.db.dbManager import DbManager
from tortuga.db.hardwareProfilesDbHandler import HardwareProfilesDbHandler
from tortuga.db.softwareProfilesDbHandler import SoftwareProfilesDbHandler
from tortuga.resourceAdapter.vmware_adapter import Vmware_adapter

session = DbManager().openSession()

dbSoftwareProfile = SoftwareProfilesDbHandler().getSoftwareProfile(
    session, 'BasicCompute')

dbHardwareProfile = HardwareProfilesDbHandler().getHardwareProfile(
    session, 'vmware2')

adapter = Vmware_adapter()

config_dict = adapter._getResourceAdapterConfig(dbHardwareProfile,
                                                dbSoftwareProfile)

pprint.pprint(config_dict)
Esempio n. 23
0
    def addHosts(self, session: Session, addHostRequest: dict) -> None:
        """
        Raises:
            HardwareProfileNotFound
            ResourceAdapterNotFound
        """

        self.getLogger().debug('addHosts()')

        dbHardwareProfile = \
            HardwareProfilesDbHandler().getHardwareProfile(
                session, addHostRequest['hardwareProfile'])

        if not dbHardwareProfile.resourceadapter:
            errmsg = ('Resource adapter not defined for hardware'
                      ' profile [%s]' % (dbHardwareProfile.name))

            self.getLogger().error(errmsg)

            raise ResourceAdapterNotFound(errmsg)

        softwareProfileName = addHostRequest['softwareProfile'] \
            if 'softwareProfile' in addHostRequest else None

        dbSoftwareProfile = \
            SoftwareProfilesDbHandler().getSoftwareProfile(
                session, softwareProfileName) \
            if softwareProfileName else None

        ResourceAdapterClass = \
            resourceAdapterFactory.get_resourceadapter_class(
                dbHardwareProfile.resourceadapter.name)

        resourceAdapter = ResourceAdapterClass(
            addHostSession=addHostRequest['addHostSession'])

        resourceAdapter.session = session

        # Call the start() method of the resource adapter
        newNodes = resourceAdapter.start(addHostRequest,
                                         session,
                                         dbHardwareProfile,
                                         dbSoftwareProfile=dbSoftwareProfile)

        session.add_all(newNodes)
        session.flush()

        if 'tags' in addHostRequest and addHostRequest['tags']:
            for node in newNodes:
                self._set_tags(node, addHostRequest['tags'])

        # Commit new node(s) to database
        session.commit()

        # Only perform post-add operations if we actually added a node
        if newNodes:
            if dbSoftwareProfile and not dbSoftwareProfile.isIdle:
                self.getLogger().info(
                    'Node(s) added to software profile [%s] and'
                    ' hardware profile [%s]' %
                    (dbSoftwareProfile.name if dbSoftwareProfile else 'None',
                     dbHardwareProfile.name))

                newNodeNames = [tmpNode.name for tmpNode in newNodes]

                resourceAdapter.hookAction('add', newNodeNames)

                self.postAddHost(session, dbHardwareProfile.name,
                                 softwareProfileName,
                                 addHostRequest['addHostSession'])

                resourceAdapter.hookAction('start', newNodeNames)

        self.getLogger().debug('Add host workflow complete')
Esempio n. 24
0
    def test_getHardwareProfileList_tag2(self):
        # 'tag2' returns hardware profile 'profile2' only
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags={'tag2': None})

        assert result and len(result) == 1 and result[0].name == 'profile2'
Esempio n. 25
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()
Esempio n. 26
0
class HardwareProfileDbApi(TagsDbApiMixin, TortugaDbApi):
    """
    HardwareProfile DB API class.

    """
    tag_model = HardwareProfileTag

    def __init__(self):
        super().__init__()

        self._hardwareProfilesDbHandler = HardwareProfilesDbHandler()
        self._nodesDbHandler = NodesDbHandler()
        self._globalParametersDbHandler = GlobalParametersDbHandler()
        self._adminsDbHandler = AdminsDbHandler()
        self._nicsDbHandler = NicsDbHandler()
        self._resourceAdaptersDbHandler = ResourceAdaptersDbHandler()
        self._networkDevicesDbHandler = NetworkDevicesDbHandler()
        self._networksDbHandler = NetworksDbHandler()

    def getHardwareProfile(self, session: Session, name: str,
                           optionDict: Optional[OptionDict] = None) \
            -> HardwareProfile:
        """
        Get hardwareProfile from the db.

            Returns:
                hardwareProfile
            Throws:
                HardwareProfileNotFound
                DbError
        """

        try:
            dbHardwareProfile = \
                self._hardwareProfilesDbHandler.getHardwareProfile(
                    session, name)

            self.loadRelations(
                dbHardwareProfile, get_default_relations(optionDict))

            return HardwareProfile.getFromDbDict(
                dbHardwareProfile.__dict__)
        except TortugaException:
            raise
        except Exception as ex:
            self._logger.exception(str(ex))
            raise

    def getHardwareProfileById(
            self, session: Session, hardwareProfileId: int,
            optionDict: Optional[OptionDict] = None) -> HardwareProfile:
        """
        Get hardwareProfile from the db.

            Returns:
                hardwareProfile
            Throws:
                HardwareProfileNotFound
                DbError
        """

        try:
            dbHardwareProfile = \
                self._hardwareProfilesDbHandler.getHardwareProfileById(
                    session, hardwareProfileId)

            self.loadRelations(
                dbHardwareProfile, get_default_relations(optionDict))

            return HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__)
        except TortugaException:
            raise
        except Exception as ex:
            self._logger.exception(str(ex))
            raise

    def getHardwareProfileList(
            self, session: Session, optionDict: Optional[OptionDict] = None,
            tags: Optional[Tags] = None) -> TortugaObjectList:
        """
        Get list of all available hardwareProfiles from the db.

            Returns:
                [hardwareProfile]
            Throws:
                DbError
        """

        try:
            dbHardwareProfileList = \
                self._hardwareProfilesDbHandler.getHardwareProfileList(
                    session, tags=tags)

            hardwareProfileList = TortugaObjectList()

            for dbHardwareProfile in dbHardwareProfileList:
                options = dict.copy(optionDict or {})
                options['hardwareprofilenetworks'] = True

                self.loadRelations(
                    dbHardwareProfile, get_default_relations(options))

                hardwareProfileList.append(
                    HardwareProfile.getFromDbDict(
                        dbHardwareProfile.__dict__))

            return hardwareProfileList
        except TortugaException:
            raise
        except Exception as ex:
            self._logger.exception(str(ex))
            raise

    def addHardwareProfile(
            self, session: Session,
            hardwareProfile: HardwareProfile) -> None:
        """
        Insert hardwareProfile into the db.

            Returns:
                (none)
            Throws:
                HardwareProfileAlreadyExists
                DbError
        """

        try:
            try:
                self._hardwareProfilesDbHandler.getHardwareProfile(
                    session, hardwareProfile.getName())

                raise HardwareProfileAlreadyExists(
                    'Hardware profile [%s] already exists' % (
                        hardwareProfile))
            except HardwareProfileNotFound as ex:
                pass

            dbHardwareProfile = self.__populateHardwareProfile(
                session, hardwareProfile)

            session.add(dbHardwareProfile)
            session.flush()
            self._set_tags(dbHardwareProfile, hardwareProfile.getTags())
            session.commit()

            self._logger.info(
                'Added hardware profile [%s]' % (dbHardwareProfile.name))
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise

    def deleteHardwareProfile(self, session: Session, name: str) -> None:
        """
        Delete hardwareProfile from the db.

            Returns:
                None
            Throws:
                HardwareProfileNotFound
                DbError
                TortugaException
        """

        try:
            hwProfile = self._hardwareProfilesDbHandler.getHardwareProfile(
                session, name)

            if hwProfile.nodes:
                raise TortugaException(
                    'Unable to delete hardware profile with associated nodes'
                )

            # First delete the mappings
            hwProfile.mappedsoftwareprofiles = []

            self._logger.debug(
                'Marking hardware profile [%s] for deletion' % (name))

            session.delete(hwProfile)

            session.commit()
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise

    def copyHardwareProfile(self, session: Session,
                            srcHardwareProfileName: str,
                            dstHardwareProfileName: str):
        #
        # Ensure the destination hardware profile doesn't already exist
        #
        try:
            self.getHardwareProfile(session, dstHardwareProfileName)
            raise TortugaException(
                'Destination hardware profile already exists: {}'.format(
                    dstHardwareProfileName)
            )
        except HardwareProfileNotFound:
            pass

        srcHardwareProfile = self.getHardwareProfile(
            session,
            srcHardwareProfileName, {
                'admins': True,
                'hardwareprofilenetworks': True,
                'nics': True,
                'resourceadapter': True,
            })

        dstHardwareProfile = \
            self.getHardwareProfile(session, srcHardwareProfileName)

        dstHardwareProfile.setName(dstHardwareProfileName)

        newDescription = 'Copy of %s' % (
            dstHardwareProfile.getDescription())

        dstHardwareProfile.setDescription(newDescription)

        dstHardwareProfile.setNetworks(srcHardwareProfile.getNetworks())

        dstHardwareProfile.setProvisioningNics(
            srcHardwareProfile.getProvisioningNics())

        dstHardwareProfile.setResourceAdapter(
            srcHardwareProfile.getResourceAdapter())

        self.addHardwareProfile(session, dstHardwareProfile)

    def addAdmin(
            self, session: Session, hardwareProfileName,
            adminUsername: str) -> None:
        """
        Add an admin to this hardware profile

        Raises:
            AdminAlreadyExists
        """

        try:
            dbAdmin = self._adminsDbHandler.getAdmin(
                session, adminUsername)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            if dbAdmin in dbHardwareProfile.admins:
                raise AdminAlreadyExists(
                    'The admin %s is already associated with %s.' % (
                        adminUsername, hardwareProfileName))

            dbHardwareProfile.admins.append(dbAdmin)

            session.commit()
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise

    def deleteAdmin(
            self, session: Session, hardwareProfileName: str,
            adminUsername: str) -> None:
        """
        Delete an admin from a hardware profile

        Raises:
            AdminNotFound
        """

        try:
            dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            if dbAdmin not in dbHardwareProfile.admins:
                raise AdminNotFound(
                    'Admin user [%s] not associated with %s.' % (
                        adminUsername, hardwareProfileName))

            dbHardwareProfile.admins.remove(dbAdmin)

            session.commit()
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise

    def updateHardwareProfile(
            self, session: Session,
            hardwareProfileObject: HardwareProfile) -> None:
        """
        Update Hardware Profile Object
        """

        try:
            dbHardwareProfile = \
                self._hardwareProfilesDbHandler.getHardwareProfileById(
                    session, hardwareProfileObject.getId())

            self.__populateHardwareProfile(
                session, hardwareProfileObject, dbHardwareProfile)
            self._set_tags(dbHardwareProfile, hardwareProfileObject.getTags())
            session.commit()

        except TortugaException:
            session.rollback()
            raise

        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise

    def __getInstallerNode(self, session: Session) -> Node:
        return self._nodesDbHandler.getNode(
            session, ConfigManager().getInstaller())

    def __get_provisioning_nics(self, session: Session) -> List[Nic]:
        return self.__getInstallerNode(session).nics

    def __get_all_networks(self, session: Session) -> List[Network]:
        return self._networksDbHandler.getNetworkList(session)

    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

    def setProvisioningNic(
            self, session: Session, hardwareProfileName: str,
            nicId: int) -> None:
        try:
            dbNic = self._nicsDbHandler.getNicById(session, nicId)

            dbHardwareProfile = self._hardwareProfilesDbHandler.\
                getHardwareProfile(session, hardwareProfileName)

            dbHardwareProfile.nics.append(dbNic)

            session.commit()
        except sqlalchemy.exc.IntegrityError as ex:
            # Entry for this hwProfile/nicId already exists, ignore
            self._logger.debug(
                'setProvisioningNic(): entry already exists for'
                ' hwProfile=%s, nicId=%d' % (hardwareProfileName, nicId))
        except TortugaException:
            raise
        except Exception as ex:
            self._logger.exception(str(ex))
            raise

    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
Esempio n. 27
0
    def test_getHardwareProfileList_tag1_and_tag2(self):
        # 'tag1' and 'tag2' returns neither profile (and operation)
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags={'tag1': None, 'tag2': None})

        assert len(result) == 0
Esempio n. 28
0
    def test_getHardwareProfile_resource_adapter_config_no_default(self):
        result = HardwareProfilesDbHandler().getHardwareProfile(
            self.session, 'aws'
        )

        assert result.default_resource_adapter_config is None
Esempio n. 29
0
    def test_no_matching_tags(self):
        # Ensure invalid tag returns no result
        result = HardwareProfilesDbHandler().getHardwareProfileList(
            self.session, tags=[('invalid', )])

        assert not result
Esempio n. 30
0
    def test_getHardwareProfileList(self):
        result = HardwareProfilesDbHandler().\
            getHardwareProfileList(self.session)

        assert isinstance(result, list)