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]
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()
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()
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
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()
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)
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()
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()
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
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))
def __validate_node(self, node): \ # pylint: disable=no-self-use """ Raises: NodeNotFound NicNotFound """ if not node.name: raise NodeNotFound('Node must have a name') if not node.nics: raise NicNotFound('Node [%s] has no associated nics' % ( node.name))
def 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
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()
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
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
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
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()
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))
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
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
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))
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()