Пример #1
0
    def get_installer_node(self, session: Session) -> Node:
        """
        Return installer node derived from searching for all software
        profiles with type 'installer'.

        Raises:
            NodeNotFound
        """

        installer_swprofiles = \
            SoftwareProfilesDbHandler().getSoftwareProfileList(
                session,
                profile_type='installer'
            )

        if not installer_swprofiles:
            raise NodeNotFound('No installer software profiles found')

        installer_nodes = installer_swprofiles[0].nodes
        if not installer_nodes:
            raise NodeNotFound(
                'No installer node found in software profile {}'.format(
                    installer_swprofiles[0].name))

        return installer_nodes[0]
Пример #2
0
    def rebootNode(self, nodespec, bSoftReset=False, bReinstall=False):
        """
        Raises:
            NodeNotFound
        """

        session = DbManager().openSession()

        try:
            nodes = self.__expand_nodespec(session, nodespec)
            if not nodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            bhm = osUtility.getOsObjectFactory().getOsBootHostManager()

            if bReinstall:
                for dbNode in nodes:
                    bhm.setNodeForNetworkBoot(dbNode)

            results = NodesDbHandler().rebootNode(session, nodes, bSoftReset)

            session.commit()

            return results
        finally:
            DbManager().closeSession()
Пример #3
0
    def shutdownNode(self, nodespec, bSoftShutdown=False):
        """
        Shutdown Node

        Raises:
            NodeNotFound
        """

        session = DbManager().openSession()

        try:
            dbNodes = self.__expand_nodespec(session, nodespec)

            if not dbNodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            self._nodesDbHandler.shutdownNode(session, dbNodes, bSoftShutdown)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()
Пример #4
0
    def shutdownNode(self, session, nodespec: str, bSoftShutdown: bool = False) \
            -> None:
        """
        Raises:
            NodeNotFound
        """

        try:
            nodes = self._nodesDbHandler.expand_nodespec(session, nodespec)

            if not nodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            d = self.__processNodeList(nodes)

            for dbHardwareProfile, detailsDict in d.items():
                # Get the ResourceAdapter
                adapter = self.__getResourceAdapter(dbHardwareProfile)

                # Call shutdown action extension
                adapter.shutdownNode(detailsDict['nodes'], bSoftShutdown)

            session.commit()
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise
Пример #5
0
    def transferNode(self, nodespec, dstSoftwareProfileName, bForce=False):
        """
        Transfer nodes defined by 'nodespec' to 'dstSoftwareProfile'

        Raises:
            NodeNotFound
            SoftwareProfileNotFound
            NodeTransferNotValid
        """

        session = DbManager().openSession()

        try:
            nodes = self.__expand_nodespec(session, nodespec)

            if not nodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            dbDstSoftwareProfile = SoftwareProfilesDbHandler().\
                getSoftwareProfile(session, dstSoftwareProfileName)

            results = NodesDbHandler().transferNode(session,
                                                    nodes,
                                                    dbDstSoftwareProfile,
                                                    bForce=bForce)

            return self.__transferNodeCommon(session, dbDstSoftwareProfile,
                                             results)
        finally:
            DbManager().closeSession()
Пример #6
0
    def getNode(self, name, optionDict: Optional[Union[dict, None]] = None):         \
            # pylint: disable=unused-argument

        url = 'nodes/?name=%s' % (urllib.parse.quote(name))

        if optionDict:
            for key, value in optionDict.items():
                if not value:
                    continue
                url += '&include={}'.format(key)

        try:
            responseDict = self.get(url)

            if not responseDict['nodes']:
                raise NodeNotFound(
                    'No nodes matching nodespec [{}]'.format(name))

            if len(responseDict['nodes']) > 1:
                raise InvalidArgument(
                    'Nodespec [{}] returned multiple results for a single'
                    ' node request; use getNodeList()'.format(name))

            return tortuga.objects.node.Node.getFromDict(
                responseDict.get('nodes')[0])

        except TortugaException:
            raise

        except Exception as ex:
            raise TortugaException(exception=ex)
Пример #7
0
    def startupNode(self, nodespec, remainingNodeList=None, bootMethod='n'):
        """
        Start Node
        """

        session = DbManager().openSession()

        try:
            dbNodes = self.__expand_nodespec(session, nodespec)

            if not dbNodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            self._nodesDbHandler.startupNode(
                session,
                dbNodes,
                remainingNodeList=remainingNodeList or [],
                bootMethod=bootMethod)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()
Пример #8
0
    def rebootNode(self,
                   session,
                   nodespec: str,
                   bSoftReset: bool = False,
                   bReinstall: bool = False) -> None:
        """
        Raises:
            NodeNotFound
        """

        nodes = self._nodesDbHandler.expand_nodespec(session, nodespec)
        if not nodes:
            raise NodeNotFound('No nodes matching nodespec [%s]' % (nodespec))

        if bReinstall:
            for dbNode in nodes:
                self._bhm.setNodeForNetworkBoot(session, dbNode)

        for dbHardwareProfile, detailsDict in \
                self.__processNodeList(nodes).items():
            # iterate over hardware profile/nodes dict to reboot each
            # node
            adapter = self.__getResourceAdapter(dbHardwareProfile)

            # Call reboot action extension
            adapter.rebootNode(detailsDict['nodes'], bSoftReset)

        session.commit()
Пример #9
0
def test_getNodesByNodeState(dbm, state):
    with dbm.session() as session:
        result = NodesDbHandler().getNodesByNodeState(session, state)

        if not result:
            raise NodeNotFound('No nodes in state [{}]'.format(state))

    assert result
Пример #10
0
    def getNodeByIp(self, session: Session, ip: str) -> Node:
        """
        Raises:
            NodeNotFound
        """

        self._logger.debug('Retrieving node by IP [%s]' % (ip))

        try:
            return session.query(Node).join(Nic).filter(Nic.ip == ip).one()
        except NoResultFound:
            raise NodeNotFound('Node with IP address [%s] not found.' % (ip))
Пример #11
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))
Пример #12
0
def test_getNodeListByNodeStateAndSoftwareProfileName(dbm, state, swprofile):
    with dbm.session() as session:
        result = NodesDbHandler().getNodeListByNodeStateAndSoftwareProfileName(
            session,
            state,
            swprofile,
        )

        if not result:
            raise NodeNotFound(
                'No nodes in software profile [{}] in state [{}]'.format(
                    state, swprofile))

    assert result
Пример #13
0
    def idleNode(self, nodespec):
        """
        Raises:
            NodeNotFound
        """

        session = DbManager().openSession()

        try:
            nodes = self.__expand_nodespec(session, nodespec)

            if not nodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            result = NodesDbHandler().idleNode(session, nodes)

            # Convert list of Nodes to list of node names for providing
            # user feedback.

            result_dict = {}
            for key, dbNodes in result.items():
                result_dict[key] = [dbNode.name for dbNode in dbNodes]

            session.commit()

            # Remove Puppet certificate(s) for idled node(s)
            for node_name in result_dict['success']:
                # Remove Puppet certificate for idled node
                bhm = osUtility.getOsObjectFactory().getOsBootHostManager()
                bhm.deletePuppetNodeCert(node_name)

            # Schedule a cluster update
            self.__scheduleUpdate()

            return result_dict
        except TortugaException as ex:
            session.rollback()

            raise
        except Exception as ex:
            session.rollback()

            self.getLogger().exception('[%s] %s' %
                                       (self.__class__.__name__, ex))

            raise
        finally:
            DbManager().closeSession()
Пример #14
0
    def __get_nodes_for_deletion(self, session: Session, nodespec: str,
                                 force: bool) -> List[NodeModel]:
        """
        :raises NodeNotFound:
        """
        nodes = self._nodesDbHandler.expand_nodespec(session,
                                                     nodespec,
                                                     include_installer=False)
        if not nodes:
            raise NodeNotFound('No nodes matching nodespec [%s]' % nodespec)

        # ensure nodes aren't locked
        self.__validate_delete_nodes_request(nodes, force)

        return nodes
Пример #15
0
    def getNodeById(self, session: Session, _id: int) -> Node:
        """
        Return node.

        Raises:
            NodeNotFound
        """

        self._logger.debug('Retrieving node by ID [%s]' % (_id))

        dbNode = session.query(Node).get(_id)

        if not dbNode:
            raise NodeNotFound('Node ID [%s] not found.' % (_id))

        return dbNode
Пример #16
0
    def __get_nodes_for_deletion(self, session: Session,
                                 nodespec: str) -> List[NodeModel]:
        """
        Gets a list of nodes from a node spec.

        :param Session session: a database session
        :param str nodespec:    a node spec

        :raise NodeNotFound:

        """
        nodes = self._nodesDbHandler.expand_nodespec(session,
                                                     nodespec,
                                                     include_installer=False)
        if not nodes:
            raise NodeNotFound(
                'No nodes matching nodespec [{}]'.format(nodespec))

        return nodes
Пример #17
0
    def activateNode(self, nodespec, softwareProfileName):
        """
        Raises:
            SoftwareProfileNotFound
            NodeNotFound
            TortugaException
        """

        session = DbManager().openSession()

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

            dbNodes = self.__expand_nodespec(session, nodespec)

            if not dbNodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            tmp_results = NodesDbHandler().activateNode(
                session, dbNodes, dbSoftwareProfile)

            results = self.__process_activateNode_results(
                tmp_results, softwareProfileName)

            session.commit()

            # Schedule a cluster update
            self.__scheduleUpdate()

            return results
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()
Пример #18
0
    def getNode(self, session: Session, name: str) -> Node:
        """
        Return node.

        Raises:
            NodeNotFound
        """

        try:
            if '.' in name:
                # Attempt exact match on fully-qualfied name
                return session.query(Node).filter(
                    func.lower(Node.name) == name.lower()).one()

            # 'name' is short host name; attempt to match on either short
            # host name or any host starting with same host name
            return session.query(Node).filter(
                or_(
                    func.lower(Node.name) == name.lower(),
                    func.lower(Node.name).like(name.lower() + '.%'))).one()
        except NoResultFound:
            raise NodeNotFound("Node [%s] not found" % (name))
Пример #19
0
    def startupNode(self,
                    session,
                    nodespec: str,
                    remainingNodeList: List[NodeModel] = None,
                    bootMethod: str = 'n') -> None:
        """
        Raises:
            NodeNotFound
        """

        try:
            nodes = self._nodesDbHandler.expand_nodespec(session, nodespec)

            if not nodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            # Break list of nodes into dict keyed on hardware profile
            nodes_dict = self.__processNodeList(nodes)

            for dbHardwareProfile, detailsDict in nodes_dict.items():
                # Get the ResourceAdapter
                adapter = self.__getResourceAdapter(dbHardwareProfile)

                # Call startup action extension
                adapter.startupNode(detailsDict['nodes'],
                                    remainingNodeList=remainingNodeList or [],
                                    tmpBootMethod=bootMethod)

            session.commit()
        except TortugaException:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self._logger.exception(str(ex))
            raise
Пример #20
0
    def deleteNode(self, session, nodespec: str, force: bool = False):
        """
        Delete node by nodespec

        Raises:
            NodeNotFound
        """

        kitmgr = KitActionsManager()
        kitmgr.session = session

        try:
            nodes = self._nodesDbHandler.expand_nodespec(
                session, nodespec, include_installer=False)
            if not nodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            self.__validate_delete_nodes_request(nodes, force)

            self.__preDeleteHost(kitmgr, nodes)

            nodeErrorDict = self.__delete_node(session, nodes)

            # REALLY!?!? Convert a list of Nodes objects into a list of
            # node names so we can report the list back to the end-user.
            # This needs to be FIXED!

            result, nodes_deleted = self.__process_nodeErrorDict(nodeErrorDict)

            session.commit()

            # ============================================================
            # Perform actions *after* node deletion(s) have been committed
            # to database.
            # ============================================================

            self.__postDeleteHost(kitmgr, nodes_deleted)

            addHostSessions = set(
                [tmpnode['addHostSession'] for tmpnode in nodes_deleted])

            if addHostSessions:
                self._addHostManager.delete_sessions(addHostSessions)

            for nodeName in result['NodesDeleted']:
                # Remove the Puppet cert
                self._bhm.deletePuppetNodeCert(nodeName)

                self._bhm.nodeCleanup(nodeName)

                self._logger.info('Node [%s] deleted' % (nodeName))

            # Schedule a cluster update
            self.__scheduleUpdate()

            return result
        except Exception:
            session.rollback()

            raise
Пример #21
0
def test_getNodesByNameFilter(dbm, nodespec):
    with dbm.session() as session:
        result = NodesDbHandler().getNodesByNameFilter(session, nodespec)
        if not result:
            raise NodeNotFound(
                'No matching nodes: nodespec=[{}]'.format(nodespec))
Пример #22
0
    def deleteNode(self, nodespec):
        """
        Delete node by nodespec

        Raises:
            NodeNotFound
        """

        installer_hostname = socket.getfqdn().split('.', 1)[0]

        session = DbManager().openSession()

        try:
            nodes = []

            for node in self.__expand_nodespec(session, nodespec):
                if node.name.split('.', 1)[0] == installer_hostname:
                    self.getLogger().info(
                        'Ignoring request to delete installer node'
                        ' ([{0}])'.format(node.name))

                    continue

                nodes.append(node)

            if not nodes:
                raise NodeNotFound('No nodes matching nodespec [%s]' %
                                   (nodespec))

            self.__preDeleteHost(nodes)

            nodeErrorDict = NodesDbHandler().deleteNode(session, nodes)

            # REALLY!?!? Convert a list of Nodes objects into a list of
            # node names so we can report the list back to the end-user.
            # This needs to be FIXED!

            result, nodes_deleted = self.__process_nodeErrorDict(nodeErrorDict)

            session.commit()

            # ============================================================
            # Perform actions *after* node deletion(s) have been committed
            # to database.
            # ============================================================

            self.__postDeleteHost(nodes_deleted)

            addHostSessions = set(
                [tmpnode['addHostSession'] for tmpnode in nodes_deleted])

            if addHostSessions:
                AddHostManager().delete_sessions(addHostSessions)

            bhm = osUtility.getOsObjectFactory().getOsBootHostManager()

            for nodeName in result['NodesDeleted']:
                # Remove the Puppet cert
                bhm.deletePuppetNodeCert(nodeName)

                bhm.nodeCleanup(nodeName)

                self.getLogger().info('Node [%s] deleted' % (nodeName))

            # Schedule a cluster update
            self.__scheduleUpdate()

            return result
        except TortugaException:
            session.rollback()

            raise
        except Exception:
            session.rollback()

            self.getLogger().exception('Exception in NodeManager.deleteNode()')

            raise
        finally:
            DbManager().closeSession()