def getprivs(self, options): """ find and return the privileges to set :param options: command line options :type options: list. """ sesprivs = self.getsesprivs() setprivs = {} availableprivs = self.getsesprivs(availableprivsopts=True) if not 'UserConfigPriv' in sesprivs.keys(): raise IdTokenError("The currently logged in account does not have the User Config "\ "privilege and cannot add or modify user accounts.") if options.optprivs: for priv in options.optprivs: priv = next(iter(priv.keys())) if priv not in availableprivs: raise IncompatibleiLOVersionError("Privilege %s is not available on this "\ "iLO version." % priv) if all(priv.values() for priv in options.optprivs): if any(priv for priv in options.optprivs if 'SystemRecoveryConfigPriv' in priv) and\ 'SystemRecoveryConfigPriv' not in sesprivs.keys(): raise IdTokenError("The currently logged in account must have The System "\ "Recovery Config privilege to add the System Recovery "\ "Config privilege.") else: setprivs = {} for priv in options.optprivs: setprivs.update(priv) return setprivs
def output_resp(self, response, dl_reg=False, verbosity=None): """Prints or logs parsed MessageId response. Will raise an IloResponseError or return a list of message response data which includes the information returned from message_handler. :param response: message response of a call. :type response: :class:`redfish.rest.containers.RestResponse` :param dl_reg: Flag to download registry. If this is set to True a generic message response will be returned instead of gathered from registries. :type dl_reg: bool :param verbosity: Optional verbosity level. Only modifies what is output to log or screen. :type verbosity: int :returns: List of error response dictionaries. """ retdata = None if response.status > 299: message_text = "No error message returned or unable to parse error response." else: message_text = "The operation completed successfully." if response.status < 300 and (response._rest_request.method == 'GET' or not response.read): warning_handler(self.verbosity_levels(message=message_text, response_status=\ response.status, verbosity=verbosity, dl_reg=dl_reg)) elif response.status == 401: raise SessionExpired() elif response.status == 403: raise IdTokenError() elif response.status == 412: warning_handler("The property you are trying to change has been updated. " \ "Please check entry again before manipulating it.\n") raise ValueChangedError() else: retdata = self.message_handler(response_data=response, verbosity=verbosity, \ message_text=message_text, dl_reg=dl_reg) if response.status > 299: raise IloResponseError("") else: return retdata
def run(self, line): """ Main iloaccounts function :param line: string of arguments passed in :type line: str. """ acct = mod_acct = None try: ident_subparser = False for cmnd in __subparsers__: if cmnd in line: (options, args) = self.rdmc.rdmc_parse_arglist(self, line) ident_subparser = True break if not ident_subparser: (options, args) = self.rdmc.rdmc_parse_arglist(self, line, default=True) except (InvalidCommandLineErrorOPTS, SystemExit): if ("-h" in line) or ("--help" in line): return ReturnCodes.SUCCESS else: raise InvalidCommandLineErrorOPTS("") self.iloaccountsvalidation(options) redfish = self.rdmc.app.monolith.is_redfish path = self.rdmc.app.typepath.defs.accountspath results = self.rdmc.app.get_handler(path, service=True, silent=True).dict if redfish: results = results['Members'] else: if 'Member' in results['links']: results = results['links']['Member'] else: results = list() for indx, acct in enumerate(results): acct = self.rdmc.app.get_handler(acct[self.rdmc.app.typepath.defs.hrefstring],\ service=True, silent=True).dict try: if hasattr(options, 'identifier'): if acct['Id'] == options.identifier or acct[ 'UserName'] == options.identifier: if redfish: path = acct['@odata.id'] else: path = acct['links']['self']['href'] mod_acct = acct elif options.command == 'default': results[indx] = acct else: raise KeyError except KeyError: continue else: if mod_acct: acct = mod_acct break if not results: raise NoContentsFoundForOperationError( "No iLO Management Accounts were found.") outdict = dict() if options.command.lower() == 'default': if not options.json: self.rdmc.ui.printer("\niLO Account info:\n\n[Id] UserName (LoginName): "\ "\nPrivileges\n-----------------\n\n", verbose_override=True) for acct in sorted(results, key=lambda k: int(k['Id'])): privstr = "" privs = acct['Oem'][ self.rdmc.app.typepath.defs.oemhp]['Privileges'] if 'ServiceAccount' in list(acct['Oem'][self.rdmc.app.typepath.defs.oemhp].keys()) \ and acct['Oem'][self.rdmc.app.typepath.defs.oemhp]['ServiceAccount']: service = 'ServiceAccount=True' else: service = 'ServiceAccount=False' if not options.json: for priv in privs: privstr += priv + '=' + str(privs[priv]) + '\n' self.rdmc.ui.printer("[%s] %s (%s):\n%s\n%s\n" % (acct['Id'], \ acct['UserName'], \ acct['Oem'][self.rdmc.app.typepath.defs.oemhp]['LoginName'], \ service, privstr), verbose_override=True) keyval = '[' + str(acct['Id']) + '] ' + acct['UserName'] outdict[keyval] = privs outdict[keyval]['ServiceAccount'] = service.split( '=')[-1].lower() if options.json: self.rdmc.ui.print_out_json_ordered(outdict) elif options.command.lower() == 'changepass': if not acct: raise InvalidCommandLineError( "Unable to find the specified account.") if not options.acct_password: self.rdmc.ui.printer('Please input the new password.\n', verbose_override=True) tempinput = getpass.getpass() self.credentialsvalidation('', '', tempinput, '', True, options) options.acct_password = tempinput account = options.identifier.lower() self.credentialsvalidation('', '', options.acct_password.split('\r')[0], '', True) body = {'Password': options.acct_password.split('\r')[0]} if path and body: self.rdmc.app.patch_handler(path, body) else: raise NoContentsFoundForOperationError( 'Unable to find the specified account.') elif options.command.lower() == 'add': if options.encode: args[2] = Encryption.decode_credentials(args[2]) if isinstance(args[2], bytes): args[2] = args[2].decode('utf-8') privs = self.getprivs(options) path = self.rdmc.app.typepath.defs.accountspath body = {"UserName": options.identifier, "Password": options.acct_password, "Oem": \ {self.rdmc.app.typepath.defs.oemhp: {"LoginName": options.loginname}}} if privs: body["Oem"][self.rdmc.app.typepath.defs.oemhp].update( {"Privileges": privs}) self.credentialsvalidation(options.identifier, options.loginname, \ options.acct_password, acct, True) if options.serviceacc: body["Oem"][self.rdmc.app.typepath.defs.oemhp].update( {"ServiceAccount": True}) if options.role: if self.rdmc.app.getiloversion() >= 5.140: body["RoleId"] = options.role else: raise IncompatibleiLOVersionError("Roles can only be set in iLO 5"\ " 1.40 or greater.") if path and body: self.rdmc.app.post_handler(path, body) elif options.command.lower() == 'modify': if not mod_acct: raise InvalidCommandLineError( "Unable to find the specified account.") body = {} if options.optprivs: body.update({ 'Oem': { self.rdmc.app.typepath.defs.oemhp: { 'Privileges': {} } } }) if any(priv for priv in options.optprivs if 'SystemRecoveryConfigPriv' in priv) \ and 'SystemRecoveryConfigPriv' not in \ self.getsesprivs().keys(): raise IdTokenError("The currently logged in account must have The System "\ "Recovery Config privilege to add the System Recovery "\ "Config privilege.") privs = self.getprivs(options) body['Oem'][ self.rdmc.app.typepath.defs.oemhp]['Privileges'] = privs if options.role and self.rdmc.app.getiloversion() >= 5.140: body["RoleId"] = options.role if not body: raise InvalidCommandLineError("Valid Privileges/RoleID have not been provided; "\ " no changes have been made to this account: %s\n" % options.identifier) self.rdmc.app.patch_handler(path, body) elif options.command.lower() == 'delete': if not acct: raise InvalidCommandLineError( "Unable to find the specified account.") self.rdmc.app.delete_handler(path) elif 'cert' in options.command.lower(): certpath = '/redfish/v1/AccountService/UserCertificateMapping/' privs = self.getsesprivs() if self.rdmc.app.typepath.defs.isgen9: IncompatibleiLOVersionError("This operation is only available on gen 10 "\ "and newer machines.") elif not privs['UserConfigPriv']: raise IdTokenError("The currently logged in account must have The User "\ "Config privilege to manage certificates for users.") else: if options.command.lower() == 'addcert': if not acct: raise InvalidCommandLineError( "Unable to find the specified account.") body = {} username = acct['UserName'] account = acct['Id'] fingerprintfile = options.certificate if os.path.exists(fingerprintfile): with open(fingerprintfile, 'r') as fingerfile: fingerprint = fingerfile.read() else: raise InvalidFileInputError('%s cannot be read.' % fingerprintfile) body = {"Fingerprint": fingerprint, "UserName": username} self.rdmc.app.post_handler(certpath, body) elif options.command.lower() == 'deletecert': if not acct: raise InvalidCommandLineError( "Unable to find the specified account.") certpath += acct['Id'] self.rdmc.app.delete_handler(certpath) else: raise InvalidCommandLineError('Invalid command.') self.cmdbase.logout_routine(self, options) #Return code return ReturnCodes.SUCCESS
def run(self, line): """ Main iloaccounts function :param line: string of arguments passed in :type line: str. """ mod_acct = None valid_args = ['add', 'delete', 'modify', 'changepass', 'addcert', 'deletecert'] try: (options, args) = self._parse_arglist(line) except (InvalidCommandLineErrorOPTS, SystemExit): if ("-h" in line) or ("--help" in line): return ReturnCodes.SUCCESS else: raise InvalidCommandLineErrorOPTS("") if len(args) > 4: raise InvalidCommandLineError("Invalid number of parameters for "\ "this command.") arg_cnt = 0 for arg in args: if arg in valid_args: arg_cnt += 1 if arg_cnt > 1: raise InvalidCommandLineError('Invalid command.') self.iloaccountsvalidation(options) redfish = self._rdmc.app.monolith.is_redfish path = self.typepath.defs.accountspath results = self._rdmc.app.get_handler(path, service=True, silent=True).dict newresults = [] if redfish: results = results['Members'] else: results = results['links']['Member'] for acct in results: acct = self._rdmc.app.get_handler(acct[self.typepath.defs.hrefstring],\ service=True, silent=True).dict if acct['Id'] in args or acct['UserName'] in args: mod_acct = acct if redfish: path = acct['@odata.id'] else: path = acct['links']['self']['href'] newresults.append(acct) results = newresults acct = mod_acct if not results: raise NoContentsFoundForOperationError("") outdict = dict() if not args: if not options.json: sys.stdout.write("iLO Account info: \n[Id] UserName (LoginName): "\ "\nPrivileges\n-----------------\n") for acct in sorted(results, key=lambda k: int(k['Id'])): privstr = "" privs = acct['Oem'][self.typepath.defs.oemhp]['Privileges'] if 'ServiceAccount' in list(acct['Oem'][self.typepath.defs.oemhp].keys()) and \ acct['Oem'][self.typepath.defs.oemhp]['ServiceAccount']: service = 'ServiceAccount=True' else: service = 'ServiceAccount=False' if not options.json: for priv in privs: privstr += priv + '=' + str(privs[priv]) + '\n' sys.stdout.write("[%s] %s (%s):\n%s\n%s\n" % (acct['Id'], acct['UserName'], \ acct['Oem'][self.typepath.defs.oemhp]['LoginName'], service, privstr)) keyval = '['+str(acct['Id'])+'] '+acct['UserName'] outdict[keyval] = privs outdict[keyval]['ServiceAccount'] = service.split('=')[-1].lower() if options.json: sys.stdout.write(str(json.dumps(outdict, indent=2, sort_keys=True))) sys.stdout.write('\n') elif args[0].lower() == 'changepass': if not mod_acct: raise InvalidCommandLineError("Unable to find the specified account.") if len(args) == 2: sys.stdout.write('Please input the new password.\n') tempinput = getpass.getpass() self.credentialsvalidation('', '', tempinput, '', True, options) args.extend([tempinput]) if len(args) == 3: account = args[1].lower() if options.encode: args[2] = Encryption.decode_credentials(args[2]) self.credentialsvalidation('', '', args[2].split('\r')[0], '', True, options) body = {'Password': args[2].split('\r')[0]} if path and body: self._rdmc.app.patch_handler(path, body) else: raise NoContentsFoundForOperationError('Unable to find the specified account.') else: raise InvalidCommandLineError('Invalid number of parameters.') elif args[0].lower() == 'add': args.remove('add') if len(args) == 2: sys.stdout.write('Please input the account password.\n') tempinput = getpass.getpass() self.credentialsvalidation('', '', tempinput, '', True, options) args.extend([tempinput]) if not len(args) == 3: raise InvalidCommandLineError('Invalid number of parameters.') if options.encode: args[2] = Encryption.decode_credentials(args[2]) privs = self.getprivs(options) path = self.typepath.defs.accountspath body = {"UserName": args[0], "Password": args[2], "Oem": {self.\ typepath.defs.oemhp: {"LoginName": args[1]}}} if privs: body["Oem"][self.typepath.defs.oemhp].update({"Privileges": privs}) self.credentialsvalidation(args[0], args[1], args[2], results, True, options) if options.serviceacc: body["Oem"][self.typepath.defs.oemhp].update({"ServiceAccount": True}) if options.role: if self._rdmc.app.getiloversion() >= 5.140: body["RoleId"] = options.role else: raise IncompatibleiLOVersionError("Roles can only be set in iLO 5"\ " 1.40 or greater.") if path and body: self._rdmc.app.post_handler(path, body) elif args[0].lower() == 'modify': if not mod_acct: raise InvalidCommandLineError("Unable to find the specified account.") body = {} args.remove('modify') if not len(args) == 1: raise InvalidCommandLineError("Invalid number of parameters.") if options.optprivs: body.update({'Oem': {self.typepath.defs.oemhp: {'Privileges': {}}}}) if any(priv for priv in options.optprivs if 'SystemRecoveryConfigPriv' in priv) \ and 'SystemRecoveryConfigPriv' not in \ self.getsesprivs().keys(): raise IdTokenError("The currently logged in account must have The System "\ "Recovery Config privilege to add the System Recovery "\ "Config privilege.") privs = self.getprivs(options) body['Oem'][self.typepath.defs.oemhp]['Privileges'] = privs if options.role and self._rdmc.app.getiloversion >= 5.140: body["RoleId"] = options.role self._rdmc.app.patch_handler(path, body) elif args[0].lower() == 'delete': if not mod_acct: raise InvalidCommandLineError("Unable to find the specified account.") self._rdmc.app.delete_handler(path) elif 'cert' in args[0].lower(): certpath = '/redfish/v1/AccountService/UserCertificateMapping/' privs = self.getsesprivs() if self.typepath.defs.isgen9: IncompatibleiLOVersionError("This operation is only available on gen 10 "\ "and newer machines.") elif privs['UserConfigPriv'] == False: raise IdTokenError("The currently logged in account must have The User "\ "Config privilege to manage certificates for users.") else: if args[0].lower() == 'addcert': if not mod_acct: raise InvalidCommandLineError("Unable to find the specified account.") body = {} args.remove('addcert') username = acct['UserName'] account = acct['Id'] if not len(args) == 2: raise InvalidCommandLineError("Invalid number of parameters.") fingerprintfile = args[1] if os.path.exists(fingerprintfile): with open(fingerprintfile, 'r') as fingerfile: fingerprint = fingerfile.read() else: raise InvalidFileInputError('%s cannot be read.' % fingerprintfile) body = {"Fingerprint": fingerprint, "UserName": username} self._rdmc.app.post_handler(certpath, body) elif args[0].lower() == 'deletecert': if not mod_acct: raise InvalidCommandLineError("Unable to find the specified account.") args.remove('deletecert') certpath += acct['Id'] self._rdmc.app.delete_handler(certpath) else: raise InvalidCommandLineError('Invalid command.') return ReturnCodes.SUCCESS
def _invalid_return_handler(self, results, print_code=None, errmessages=None): """Main worker function for printing/raising all error messages :param results: dict of the results. :type results: sict. :param errmessages: dict of lists containing the systems error messages. :type errmessages: dict. :param print_code: Flag to also always print the return code. :type print_code: boolean. """ output = '' try: contents = results.dict["Messages"][0]["MessageID"].split('.') except Exception: try: contents = results.dict["error"]["@Message.ExtendedInfo"][0][ "MessageId"].split('.') except Exception: if results.status == 200 or results.status == 201: if print_code: warning_handler("[%d] The operation completed " \ "successfully.\n" % results.status) else: warning_handler("[%d] The operation completed " \ "successfully.\n" % results.status) elif results.status == 412: warning_handler("The property you are trying to " \ "change has been updated. Please " \ "check entry again before manipulating it.\n") raise ValueChangedError("") elif results.status == 403: raise IdTokenError() else: warning_handler("[%d] No message returned by iLO.\n" % results.status) raise IloResponseError("") return if results.status == 401 and not contents[-1].lower( ) == 'insufficientprivilege': raise SessionExpired() elif results.status == 403: raise IdTokenError() elif results.status == 412: warning_handler("The property you are trying to change " \ "has been updated. Please check entry again " \ " before manipulating it.\n") raise ValueChangedError() elif errmessages: for messagetype in list(errmessages.keys()): if contents[0] == messagetype: try: if errmessages[messagetype][ contents[-1]]["NumberOfArgs"] == 0: output = errmessages[messagetype][ contents[-1]]["Message"] else: output = errmessages[messagetype][ contents[-1]]["Description"] if print_code: warning_handler("[%d] %s\n" % (results.status, output)) if results.status == 200 or results.status == 201: warning_handler("{0}\n".format(output)) if not results.status == 200 and not results.status == 201: warning_handler("iLO response with code [%d]:"\ " %s\n" % (results.status, output)) raise IloResponseError("") break except IloResponseError as excp: raise excp except Exception: pass if not output: if results.status == 200 or results.status == 201: warning_handler( "[%d] The operation completed successfully.\n" % results.status) else: warning_handler("[{0}] iLO error response: {1}\n".\ format(results.status, contents)) raise IloResponseError("") else: if results.status == 200 or results.status == 201: if print_code: warning_handler( "[%d] The operation completed successfully.\n" % results.status) else: warning_handler("The operation completed successfully.\n") elif contents: warning_handler("iLO response with code [{0}]: {1}\n".\ format(results.status, contents)) raise IloResponseError("") else: warning_handler("[%d] No message returned.\n" % results.status)
def run(self, line): """Main directory Function :param line: string of arguments passed in :type line: str. """ try: _subcommands = ['ldap', 'kerberos', 'test'] found = False for i, arg in enumerate(line): if arg in _subcommands: found = True try: if line[i+1] not in self.parser._option_string_actions.keys(): (options, args) = self._parse_arglist(line) else: raise IndexError except (KeyError, IndexError): (options, args) = self._parse_arglist(line, default=True) else: continue if not found: (options, args) = self._parse_arglist(line, default=True) except (InvalidCommandLineErrorOPTS, SystemExit): if ("-h" in line) or ("--help" in line): return ReturnCodes.SUCCESS else: raise InvalidCommandLineErrorOPTS("") self.directoryvalidation(options) if self._rdmc.app.getiloversion() < 5.140: raise IncompatibleiLOVersionError("Directory settings are only available on "\ "iLO 5 1.40 or greater.") results = None if options.command.lower() == 'ldap' or ((True if options.ldap_kerberos == 'ldap' \ else False) if hasattr(options, 'ldap_kerberos') else False): try: results = self._rdmc.app.select(selector='AccountService.', \ path_refresh=True)[0].dict path = results[self._rdmc.app.typepath.defs.hrefstring] oem = results['Oem'][self.typepath.defs.oemhp] local_auth = results['LocalAccountAuth'] results = results['LDAP'] name = 'LDAP' except (KeyError, IndexError): raise NoContentsFoundForOperationError("Unable to gather LDAP settings.") elif options.command.lower() == 'kerberos' or ((True if options.ldap_kerberos == \ 'kerberos' else False) if hasattr(options, 'ldap_kerberos') else False): try: results = self._rdmc.app.select(selector='AccountService.', \ path_refresh=True)[0].dict path = results[self._rdmc.app.typepath.defs.hrefstring] oem = results['Oem'][self.typepath.defs.oemhp] local_auth = results['LocalAccountAuth'] results = results['ActiveDirectory'] name = 'ActiveDirectory' except (KeyError, IndexError): raise NoContentsFoundForOperationError("Unable to gather Kerberos settings.") if results: keytab = None payload = {} if hasattr(options, 'keytab'): keytab = options.keytab try: directory_settings = self.directory_helper(results, options) except IndexError: directory_settings = self.directory_helper(results, options) if directory_settings: payload[name] = directory_settings if hasattr(options, 'authmode'): if options.authmode: payload.update({'Oem':{'Hpe':{'DirectorySettings': \ {'LdapAuthenticationMode': options.authmode}}}}) if not payload and not keytab: if options.json: UI().print_out_json({name: results, 'LocalAccountAuth': local_auth, \ "Oem": {"Hpe": oem}}) else: self.print_settings(results, oem, local_auth, name) if payload: priv_patches = {} try: if hasattr(options, "localauth"): if options.localauth: payload['LocalAccountAuth'] = 'Enabled' \ if options.localauth else 'Disabled' elif local_auth: payload['LocalAccountAuth'] = 'Enabled' if local_auth else 'Disabled' except NameError, AttributeError: payload['LocalAccountAuth'] = 'Disabled' try: maps = {} if payload.get('LDAP'): maps = payload['LDAP'].get('RemoteRoleMapping', {}) elif payload.get('ActiveDirectory'): maps = payload['ActiveDirectory'].get('RemoteRoleMapping', {}) #Check if we need to modify roles after creating for mapping in maps: privs = mapping['LocalRole'].split(';') if len(privs) > 1: privs = [int(priv) for priv in privs if priv] if 10 in privs: user_privs = self.iloaccounts.getsesprivs() if 'SystemRecoveryConfigPriv' not in user_privs.keys(): raise IdTokenError("The currently logged in account "\ "must have the System Recovery Config privilege to "\ "add the System Recovery Config privilege to a local "\ "role group.") priv_patches[mapping['RemoteGroup']] = privs mapping['LocalRole'] = "ReadOnly" except Exception: pass sys.stdout.write("Changing settings...\n") try: self._rdmc.app.patch_handler(path, payload) except IloResponseError: if not results['ServiceEnabled']: sys.stderr.write("You must enable this directory service before or during"\ " assignment of username and password. Try adding the flag --enable.\n") raise IloResponseError("") else: raise if priv_patches: self.update_mapping_privs(priv_patches) if keytab: path = oem['Actions'][next(iter(oem['Actions']))]['target'] sys.stdout.write("Adding keytab...\n") self._rdmc.app.post_handler(path, {"ImportUri": keytab})
def createtask(self, tasks, options): """ Creates a task in the update task queue :param tasks: arguments for creating tasks :type tasks: list. :param options: command line options :type options: list. """ tpmflag = False try: results = self._rdmc.app.get_handler(self.typepath.defs.biospath) contents = results.dict if self.typepath.defs.isgen9 else results.dict[ "Attributes"] tpmstate = contents["TpmState"] if not "Not" in tpmstate or not "Disabled" in tpmstate: if options.tover: tpmflag = True else: raise IdTokenError('') except: pass path = '/redfish/v1/UpdateService/UpdateTaskQueue/' comps = self._rdmc.app.getcollectionmembers('/redfish/v1/UpdateService/'\ 'ComponentRepository/') for task in tasks: usedcomp = None newtask = None try: usedcomp = int(task) newtask = {'Name': 'Wait-%s %s seconds' % (str(randint(0, \ 1000000)), str(usedcomp)), 'Command': 'Wait', \ 'WaitTimeSeconds':usedcomp, 'UpdatableBy':[\ 'RuntimeAgent', 'Uefi'], 'TPMOverride': tpmflag} except: pass if task.lower() == 'reboot': newtask = {'Name': 'Reboot-%s' % str(randint(0, 1000000)), \ 'Command': 'ResetServer', 'UpdatableBy': \ ['RuntimeAgent'], 'TPMOverride': tpmflag} elif not newtask: try: for comp in comps: if comp['Filename'] == task: usedcomp = comp break except: pass if not usedcomp: raise NoContentsFoundForOperationError('Component ' \ 'referenced is not present on iLO Drive: %s' % task) newtask = {'Name': 'Update-%s %s' % (str(randint(0, 1000000)), \ usedcomp['Name'].encode("ascii", "ignore")), 'Command': 'ApplyUpdate',\ 'Filename': usedcomp['Filename'], 'UpdatableBy': usedcomp\ ['UpdatableBy'], 'TPMOverride': True} sys.stdout.write('Creating task: "%s"\n' % newtask['Name'].encode("ascii", "ignore")) self._rdmc.app.post_handler(path, newtask)
def run(self, line): """ Main addfederation function :param line: string of arguments passed in :type line: str. """ mod_fed = None body = dict() try: ident_subparser = False for cmnd in __subparsers__: if cmnd in line: (options, args) = self.rdmc.rdmc_parse_arglist(self, line) ident_subparser = True break if not ident_subparser: (options, args) = self.rdmc.rdmc_parse_arglist(self, line, default=True) except (InvalidCommandLineErrorOPTS, SystemExit): if ("-h" in line) or ("--help" in line): return ReturnCodes.SUCCESS else: raise InvalidCommandLineErrorOPTS("") self.addfederationvalidation(options) redfish = self.rdmc.app.monolith.is_redfish path = self.rdmc.app.typepath.defs.federationpath results = self.rdmc.app.get_handler(path, service=True, silent=False).dict newresults = [] if redfish: results = results['Members'] else: if 'Member' in results['links']: results = results['links']['Member'] else: results = list() for fed in results: fed = self.rdmc.app.get_handler(fed[self.rdmc.app.typepath.defs.hrefstring], \ service=True, silent=True).dict if hasattr(options, 'fedname') or hasattr(options, 'fedkey'): mod_fed = fed if redfish: path = fed['@odata.id'] else: path = fed['links']['self']['href'] newresults.append(fed) results = newresults fed = mod_fed if not results: raise NoContentsFoundForOperationError( "No iLO Federation accounts were found.") if options.command.lower() == 'add': privs = self.getprivs(options) path = self.rdmc.app.typepath.defs.federationpath body = {"Name": options.fedname, "Key": options.fedkey} if privs: body.update({"Privileges": privs}) self.addvalidation(options.fedname, options.fedkey, results) if path and body: resp = self.rdmc.app.post_handler(path, body) if resp and resp.dict: if 'resourcealreadyexist' in str(resp.dict).lower(): raise ResourceExists('') elif options.command.lower() == 'changekey': try: name = options.fedname newkey = options.fedkey except: raise InvalidCommandLineError('Invalid number of parameters.') for fed in results: if fed['Name'] == name: if redfish: path = fed['@odata.id'] break else: path = fed['links']['self']['href'] break body = {'Key': newkey} if path and body: self.rdmc.app.patch_handler(path, body, service=True) else: raise NoContentsFoundForOperationError('Unable to find '\ 'the specified federation.') elif options.command.lower() == 'modify': if not mod_fed: raise InvalidCommandLineError( "Unable to find the specified federation.") name = options.fedname for fed in results: if fed['Name'] == name: if redfish: path = fed['@odata.id'] break else: path = fed['links']['self']['href'] break if options.optprivs: body.update({'Privileges': {}}) if any(priv for priv in options.optprivs if 'SystemRecoveryConfigPriv' in priv) \ and 'SystemRecoveryConfigPriv' not in \ self.getsesprivs().keys(): raise IdTokenError("The currently logged in federation must have The System "\ "Recovery Config privilege to add the System Recovery "\ "Config privilege.") privs = self.getprivs(options) body['Privileges'] = privs self.rdmc.app.patch_handler(path, body) elif options.command.lower() == 'delete': if not mod_fed: raise InvalidCommandLineError( "Unable to find the specified Federation.") name = options.fedname for fed in results: if fed['Name'] == name: if redfish: path = fed['@odata.id'] break else: path = fed['links']['self']['href'] break if not path == self.rdmc.app.typepath.defs.federationpath: self.rdmc.app.delete_handler(path) else: raise NoContentsFoundForOperationError( 'Unable to find the specified federation.') else: self.rdmc.ui.printer("iLO Federation Id list with Privileges:\n") if options.json: outdict = dict() for fed in sorted(results, key=lambda k: k['Name']): outdict[fed['Name']] = fed['Privileges'] self.rdmc.ui.print_out_json_ordered( str(json.dumps(outdict, indent=2))) else: for fed in sorted(results, key=lambda k: k['Name']): privstr = "" privs = fed['Privileges'] for priv in privs: privstr += priv + '=' + str(privs[priv]) + '\n' self.rdmc.ui.printer("\nName=%s:\n%s" % (fed['Name'], privstr)) self.cmdbase.logout_routine(self, options) #Return code return ReturnCodes.SUCCESS
def run(self, line): """ Main addfederation function :param line: string of arguments passed in :type line: str. """ mod_fed = None valid_args = ['add', 'delete', 'modify', 'changekey'] try: (options, args) = self._parse_arglist(line) except (InvalidCommandLineErrorOPTS, SystemExit): if ("-h" in line) or ("--help" in line): return ReturnCodes.SUCCESS else: raise InvalidCommandLineErrorOPTS("") if len(args) > 4: raise InvalidCommandLineError("Invalid number of parameters for "\ "this command.") arg_cnt = 0 for arg in args: if arg in valid_args: arg_cnt += 1 if arg_cnt > 1: raise InvalidCommandLineError("Invalid command.") self.addfederationvalidation(options) redfish = self._rdmc.app.monolith.is_redfish path = self.typepath.defs.federationpath results = self._rdmc.app.get_handler(path, service=True, silent=True).dict newresults = [] if redfish: results = results['Members'] else: results = results['links']['Member'] for fed in results: fed = self._rdmc.app.get_handler(fed[self.typepath.defs.hrefstring], \ service=True, silent=True).dict if fed['Name'] in args or fed['Id'] in args: mod_fed = fed if redfish: path = fed['@odata.id'] else: path = fed['links']['self']['href'] newresults.append(fed) results = newresults fed = mod_fed if not results: raise NoContentsFoundForOperationError("") if not args: sys.stdout.write("iLO Federation Id list with Privileges:\n") for fed in sorted(results, key=lambda k: k['Name']): privstr = "" privs = fed['Privileges'] for priv in privs: privstr += priv + '=' + str(privs[priv]) + '\n' sys.stdout.write("\nName=%s:\n%s" % (fed['Name'], privstr)) elif args[0].lower() == 'add': args.remove('add') if len(args) == 1: sys.stdout.write("Please input the federation key.\n") tempinput = getpass.getpass() args.extend([tempinput]) privs = self.getprivs(options) path = self.typepath.defs.federationpath body = {"Name": args[0], "Key": args[1]} if privs: body.update({"Privileges": privs}) self.addvalidation(args[0], args[1], results) if path and body: resp = self._rdmc.app.post_handler(path, body, response=True) if resp and resp.dict: if 'resourcealreadyexist' in str(resp.dict).lower(): raise ResourceExists('') elif args[0].lower() == 'changekey': args.remove('changekey') try: name = args[0] newkey = args[1] except: raise InvalidCommandLineError('Invalid number of parameters.') for fed in results: if fed['Name'] == name: if redfish: path = fed['@odata.id'] break else: path = fed['links']['self']['href'] break body = {'Key': newkey} if path and body: self._rdmc.app.patch_handler(path, body, service=True) else: raise NoContentsFoundForOperationError('Unable to find '\ 'the specified federation.') elif args[0].lower() == 'modify': if not mod_fed: raise InvalidCommandLineError( "Unable to find the specified federation.") body = {} args.remove('modify') if not len(args) == 1: raise InvalidCommandLineError("Invalid number of parameters.") if options.optprivs: body.update({'Privileges': {}}) if any(priv for priv in options.optprivs if 'SystemRecoveryConfigPriv' in priv) \ and 'SystemRecoveryConfigPriv' not in \ self.getsesprivs().keys(): raise IdTokenError("The currently logged in federation must have The System "\ "Recovery Config privilege to add the System Recovery "\ "Config privilege.") privs = self.getprivs(options) body['Privileges'] = privs self._rdmc.app.patch_handler(path, body) elif args[0].lower() == 'delete': if not mod_fed: raise InvalidCommandLineError( "Unable to find the specified Federation.") args.remove('delete') try: name = str(args[0]) except: raise InvalidCommandLineError("No Name entered to delete.") for fed in results: if fed['Name'] == name: if redfish: path = fed['@odata.id'] break else: path = fed['links']['self']['href'] break if not path == self.typepath.defs.federationpath: self._rdmc.app.delete_handler(path) else: raise NoContentsFoundForOperationError( 'Unable to find the specified federation.') else: raise InvalidCommandLineError('Invalid command.') return ReturnCodes.SUCCESS
def createtask(self, tasks, options): """ Creates a task in the update task queue :param tasks: arguments for creating tasks :type tasks: list. :param options: command line options :type options: list. """ tpmflag = None path = '/redfish/v1/UpdateService/UpdateTaskQueue/' comps = self._rdmc.app.getcollectionmembers('/redfish/v1/UpdateService/'\ 'ComponentRepository/') curr_tasks = self._rdmc.app.getcollectionmembers(\ '/redfish/v1/UpdateService/UpdateTaskQueue/') for task in tasks: usedcomp = None newtask = None try: usedcomp = int(task) newtask = {'Name': 'Wait-%s %s seconds' % (str(randint(0, \ 1000000)), str(usedcomp)), 'Command': 'Wait', \ 'WaitTimeSeconds':usedcomp, 'UpdatableBy':[\ 'Bmc']} except ValueError: pass if task.lower() == 'reboot': newtask = {'Name': 'Reboot-%s' % str(randint(0, 1000000)), \ 'Command': 'ResetServer', 'UpdatableBy': \ ['RuntimeAgent']} elif not newtask: if tpmflag is None: if options.tover: tpmflag = True else: tpmflag = False #TODO: Update to monolith check results = self._rdmc.app.get_handler(self.typepath.defs.biospath, silent=True) if results.status == 200: contents = results.dict if self.typepath.defs.isgen9 else \ results.dict["Attributes"] tpmstate = contents["TpmState"] if "Enabled" in tpmstate and not tpmflag: raise IdTokenError('') for curr_task in curr_tasks: if 'Filename' in curr_task and curr_task['Filename'] == task \ and curr_task['State'].lower() is not 'exception': raise TaskQueueError("This file already has a task queue for flashing "\ "associated with it. Reset the taskqueue and "\ "retry if you need to add this task again.") for comp in comps: if comp['Filename'] == task: usedcomp = comp break if not usedcomp: raise NoContentsFoundForOperationError('Component ' \ 'referenced is not present on iLO Drive: %s' % task) newtask = {'Name': 'Update-%s %s' % (str(randint(0, 1000000)), \ usedcomp['Name'].encode("ascii", "ignore")), 'Command': 'ApplyUpdate',\ 'Filename': usedcomp['Filename'], 'UpdatableBy': usedcomp\ ['UpdatableBy'], 'TPMOverride': tpmflag} sys.stdout.write('Creating task: "%s"\n' % newtask['Name'].encode("ascii", "ignore")) self._rdmc.app.post_handler(path, newtask)