Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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})
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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
Ejemplo n.º 10
0
    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)