def addSoftwareProfile(self, softwareProfile, session=None): """ Insert software profile into the db. Raises: SoftwareProfileAlreadyExists DbError """ # Keep local 'session' instance. If 'session' is None, # ensure transaction is committed before returning to the # caller, otherwise the caller is responsible. On exceptions, # the rollback is performed regardless. _session = session if _session is None: _session = DbManager().openSession() try: try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile( _session, softwareProfile.getName()) raise SoftwareProfileAlreadyExists( 'Software profile [%s] already exists' % (softwareProfile)) except SoftwareProfileNotFound as ex: pass dbSoftwareProfile = self.__populateSoftwareProfile( _session, softwareProfile) _session.query(func.max(SoftwareProfiles.id)).one() softwareProfile.setId(dbSoftwareProfile.id) if session is None: _session.commit() self.getLogger().info('Added software profile [%s]' % (dbSoftwareProfile.name)) return dbSoftwareProfile except TortugaException as ex: _session.rollback() raise except Exception as ex: _session.rollback() self.getLogger().exception('%s' % ex) raise finally: if session is None: DbManager().closeSession()
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()