iLO-manager first main commitgit status
This commit is contained in:
1 parent
e6f4cc04ca
commit
599d8da562
3271 files changed
+550655
No files matched your search
+156
@@ -0,0 +1,156 @@
|
||||
###
|
||||
# Copyright 2016-2021 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""BiosDefaultsCommand for rdmc"""
|
||||
|
||||
try:
|
||||
from rdmc_helper import Encryption, InvalidCommandLineErrorOPTS, ReturnCodes
|
||||
except ImportError:
|
||||
from ilorest.rdmc_helper import Encryption, InvalidCommandLineErrorOPTS, ReturnCodes
|
||||
|
||||
|
||||
class BiosDefaultsCommand:
|
||||
"""Set BIOS settings back to default for the server that is currently
|
||||
logged in"""
|
||||
|
||||
def __init__(self):
|
||||
self.ident = {
|
||||
"name": "biosdefaults",
|
||||
"usage": None,
|
||||
"description": "Run to set the currently"
|
||||
" logged in server's Bios. type settings to defaults\n\texample: "
|
||||
"biosdefaults\n\n\tRun to set the currently logged in server's "
|
||||
"Bios. type settings to user defaults\n\texample: biosdefaults "
|
||||
"--userdefaults\n\n\tRun to set the currently logged in server "
|
||||
"to manufacturing defaults, including boot order and secure boot."
|
||||
"\n\texample: biosdefaults --manufacturingdefaults",
|
||||
"summary": "Set the currently logged in server to default BIOS settings.",
|
||||
"aliases": [],
|
||||
"auxcommands": ["SetCommand", "RebootCommand"],
|
||||
}
|
||||
self.cmdbase = None
|
||||
self.rdmc = None
|
||||
self.auxcommands = dict()
|
||||
|
||||
def run(self, line, help_disp=False):
|
||||
"""Main BIOS defaults worker function"""
|
||||
if help_disp:
|
||||
self.parser.print_help()
|
||||
return ReturnCodes.SUCCESS
|
||||
try:
|
||||
(options, _) = self.rdmc.rdmc_parse_arglist(self, line)
|
||||
except (InvalidCommandLineErrorOPTS, SystemExit):
|
||||
if ("-h" in line) or ("--help" in line):
|
||||
return ReturnCodes.SUCCESS
|
||||
else:
|
||||
raise InvalidCommandLineErrorOPTS("")
|
||||
|
||||
self.defaultsvalidation(options)
|
||||
|
||||
if options.manufdefaults:
|
||||
self.rdmc.ui.printer("Resetting BIOS attributes and settings to manufacturing defaults.\n")
|
||||
elif options.userdefaults:
|
||||
self.rdmc.ui.printer("Resetting BIOS attributes and settings to user defaults.\n")
|
||||
|
||||
put_path = self.rdmc.app.typepath.defs.biospath
|
||||
body = None
|
||||
|
||||
if self.rdmc.app.typepath.defs.isgen10 and not options.manufdefaults:
|
||||
bodydict = self.rdmc.app.get_handler(self.rdmc.app.typepath.defs.biospath, service=True, silent=True).dict
|
||||
|
||||
for item in bodydict["Actions"]:
|
||||
if "ResetBios" in item:
|
||||
action = item.split("#")[-1]
|
||||
path = bodydict["Actions"][item]["target"]
|
||||
break
|
||||
|
||||
body = {"Action": action}
|
||||
|
||||
if options.userdefaults:
|
||||
body["ResetType"] = "default.user"
|
||||
else:
|
||||
body["ResetType"] = "default"
|
||||
|
||||
self.rdmc.app.post_handler(path, body)
|
||||
else:
|
||||
if options.userdefaults:
|
||||
body = {"BaseConfig": "default.user"}
|
||||
elif not options.manufdefaults:
|
||||
body = {"BaseConfig": "default"}
|
||||
if body:
|
||||
self.rdmc.app.put_handler(
|
||||
put_path + "/settings",
|
||||
body=body,
|
||||
optionalpassword=options.biospassword,
|
||||
)
|
||||
|
||||
if not body and options.manufdefaults:
|
||||
setstring = "RestoreManufacturingDefaults=Yes --selector=HpBios. --commit"
|
||||
if options.reboot:
|
||||
setstring += " --reboot=%s" % options.reboot
|
||||
|
||||
self.auxcommands["set"].run(setstring)
|
||||
|
||||
elif options.reboot:
|
||||
self.auxcommands["reboot"].run(options.reboot)
|
||||
|
||||
self.cmdbase.logout_routine(self, options)
|
||||
# Return code
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
def defaultsvalidation(self, options):
|
||||
"""BIOS defaults method validation function"""
|
||||
self.cmdbase.login_select_validation(self, options)
|
||||
|
||||
if options.encode:
|
||||
options.biospassword = Encryption.decode_credentials(options.biospassword)
|
||||
if isinstance(options.biospassword, bytes):
|
||||
options.biospassword = options.biospassword.decode("utf-8")
|
||||
|
||||
def definearguments(self, customparser):
|
||||
"""Wrapper function for new command main function
|
||||
|
||||
:param customparser: command line input
|
||||
:type customparser: parser.
|
||||
"""
|
||||
if not customparser:
|
||||
return
|
||||
|
||||
self.cmdbase.add_login_arguments_group(customparser)
|
||||
|
||||
customparser.add_argument(
|
||||
"--reboot",
|
||||
dest="reboot",
|
||||
help="Use this flag to perform a reboot command function after"
|
||||
" completion of operations. For help with parameters and"
|
||||
" descriptions regarding the reboot flag, run help reboot.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--userdefaults",
|
||||
dest="userdefaults",
|
||||
action="store_true",
|
||||
help="Sets bios to user defaults instead of manufacturing defaults.",
|
||||
default=False,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--manufacturingdefaults",
|
||||
dest="manufdefaults",
|
||||
action="store_true",
|
||||
help="Reset all configuration settings to manufacturing defaults, " "including boot order and secure boot.",
|
||||
default=False,
|
||||
)
|
||||
+746
@@ -0,0 +1,746 @@
|
||||
###
|
||||
# Copyright 2016-2021 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""BootOrder Command for rdmc"""
|
||||
|
||||
import ast
|
||||
import copy
|
||||
import fnmatch
|
||||
from functools import reduce
|
||||
|
||||
import six
|
||||
|
||||
try:
|
||||
from rdmc_helper import (
|
||||
UI,
|
||||
BootOrderMissingEntriesError,
|
||||
Encryption,
|
||||
InvalidCommandLineError,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
InvalidOrNothingChangedSettingsError,
|
||||
ReturnCodes,
|
||||
)
|
||||
except:
|
||||
from ilorest.rdmc_helper import (
|
||||
UI,
|
||||
BootOrderMissingEntriesError,
|
||||
Encryption,
|
||||
InvalidCommandLineError,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
InvalidOrNothingChangedSettingsError,
|
||||
ReturnCodes,
|
||||
)
|
||||
|
||||
|
||||
class BootOrderCommand:
|
||||
"""Changes the boot order for the server that is currently logged in"""
|
||||
|
||||
def __init__(self):
|
||||
self.ident = {
|
||||
"name": "bootorder",
|
||||
"usage": None,
|
||||
"description": "Run without arguments for current boot order and one time boot options."
|
||||
"\n\texample: bootorder\n\n\tTo set the persistent boot order pick items "
|
||||
'from\n\tthe "Current Persistent Boot Order" section.\n\t'
|
||||
"example: bootorder [5,4,3,2,1] --commit\n\n\tSetting partial"
|
||||
" boot order is also supported.\n\tMissing entries are "
|
||||
"concatenated at the end.\n\texample: bootorder [5] --commit\n\n\t"
|
||||
"You can also set the boot order using partial string matching.\n\t"
|
||||
"example: bootorder NIC.*v4 HD* Generic.USB.1.1 --commit\n\n\tThis will set "
|
||||
"All v4 NICs first, followed by all hard drives,\n\tfollowed by Generic.USB.1.1. "
|
||||
"Everything not listed will be\n\tadded to the end of the boot order."
|
||||
'\n\n\tTo set one time boot entry pick items from the\n\t"'
|
||||
'Continuous and one time boot uefi options" section.\n\t'
|
||||
"example: bootorder --onetimeboot=Hdd\n\n\tTo set continuous"
|
||||
' boot entry pick items from the\n\t"Continuous and one time '
|
||||
'boot uefi options" section.\n\texample: bootorder --'
|
||||
"continuousboot=Utilities --commit\n\n\tDisable either "
|
||||
"continuous or one time boot options.\n\texample: bootorder "
|
||||
"--disablebootflag --commit\n\n\t"
|
||||
"Changing Secure Boot Keys:\n\tTo manage secure boot keys use"
|
||||
" the --securebootkeys flag.\n\tTo delete all keys.\n\n\texample:"
|
||||
" bootorder --securebootkeys=deletepk\n\tFor all possibilities"
|
||||
" see the --securebootkeys flag \n\tin the options list.\n\n\t"
|
||||
"NOTE: pick ONETIMEBOOT and "
|
||||
'CONTINUOUS items from "Continuous\n\tand one time boot '
|
||||
'options" section. Items in this list represent\n\ta '
|
||||
'"clustered" view of the "Continuous and one time boot uefi'
|
||||
'\n\toptions" section. Example: choosing Pxe will try to Pxe'
|
||||
' boot\n\tcapable devices in the order found in the "'
|
||||
'Continuous and one\n\ttime boot options".\n\n\t',
|
||||
"summary": "Displays and sets the current boot order.",
|
||||
"aliases": [],
|
||||
"auxcommands": [
|
||||
"GetCommand",
|
||||
"SelectCommand",
|
||||
"SetCommand",
|
||||
"RebootCommand",
|
||||
],
|
||||
}
|
||||
self.cmdbase = None
|
||||
self.rdmc = None
|
||||
self.auxcommands = dict()
|
||||
|
||||
def run(self, line, help_disp=False):
|
||||
"""Main boot order worker function"""
|
||||
if help_disp:
|
||||
self.parser.print_help()
|
||||
return ReturnCodes.SUCCESS
|
||||
try:
|
||||
(options, args) = self.rdmc.rdmc_parse_arglist(self, line)
|
||||
except (InvalidCommandLineErrorOPTS, SystemExit):
|
||||
if ("-h" in line) or ("--help" in line):
|
||||
return ReturnCodes.SUCCESS
|
||||
else:
|
||||
raise InvalidCommandLineErrorOPTS("")
|
||||
|
||||
self.bootordervalidation(options)
|
||||
|
||||
if options.secureboot:
|
||||
self.secureboothelper(options.secureboot)
|
||||
|
||||
if options.reboot:
|
||||
self.auxcommands["reboot"].run(options.reboot)
|
||||
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
self.rdmc.app.select(selector="HpeServerBootSettings.", path_refresh=True)
|
||||
|
||||
props = self.rdmc.app.getprops(skipnonsetting=False)
|
||||
|
||||
for prop in props:
|
||||
bootname = prop.get("Name")
|
||||
|
||||
self.rdmc.ui.printer("bootname is : {0}\n\n".format(bootname))
|
||||
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
if "current" in bootname.lower() or "pending" in bootname.lower():
|
||||
try:
|
||||
bootpath = prop.get("@odata.id")
|
||||
except:
|
||||
bootpath = prop.get("links")
|
||||
else:
|
||||
bootpath = "/rest/v1/systems/1/bios/boot"
|
||||
|
||||
self.rdmc.ui.printer("bootpath is : {0}\n\n".format(bootpath))
|
||||
|
||||
bootsources = self.rdmc.app.get_handler(bootpath, service=True, silent=True).dict["BootSources"]
|
||||
|
||||
bootoverride = None
|
||||
self.auxcommands["select"].selectfunction("HpeBios.")
|
||||
try:
|
||||
bootmode = self.auxcommands["get"].getworkerfunction("BootMode", options, results=True, uselist=True)
|
||||
except:
|
||||
bootmode = dict()
|
||||
bootmode["BootMode"] = "Uefi"
|
||||
|
||||
self.auxcommands["select"].selectfunction("ComputerSystem.")
|
||||
onetimebootsettings = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/" + self.rdmc.app.typepath.defs.bootoverridetargettype],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
|
||||
bootstatus = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/BootSourceOverrideEnabled"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
|
||||
targetstatus = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/BootSourceOverrideTarget"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
|
||||
uefitargetstatus = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/UefiTargetBootSourceOverride"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
|
||||
currentsettings = self.rdmc.app.get_handler(self.rdmc.app.typepath.defs.systempath, service=True, silent=True)
|
||||
|
||||
if bootmode and bootmode[0].get("BootMode", None) == "Uefi":
|
||||
if self.rdmc.app.typepath.defs.isgen9:
|
||||
uefionetimebootsettings = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/UefiTargetBootSourceOverrideSupported"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
|
||||
else:
|
||||
# Gen 10
|
||||
bootsettings = self.auxcommands["get"].getworkerfunction(
|
||||
["Boot"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)[0]["Boot"]
|
||||
finaluefi = []
|
||||
if "UefiTargetBootSourceOverride@Redfish.AllowableValues" in bootsettings:
|
||||
uefionetimebootsettings = bootsettings["UefiTargetBootSourceOverride@Redfish.AllowableValues"]
|
||||
|
||||
for setting in uefionetimebootsettings:
|
||||
for source in bootsources:
|
||||
if "UEFIDevicePath" in source and source["UEFIDevicePath"].endswith(setting):
|
||||
finaluefi.append(source["StructuredBootString"])
|
||||
continue
|
||||
|
||||
uefionetimebootsettings = {"Boot": {"UefiTargetBootSourceOverrideSupported": finaluefi}}
|
||||
else:
|
||||
uefionetimebootsettings = None
|
||||
|
||||
if options.onetimeboot is None and options.continuousboot is None and not options.disablebootflag:
|
||||
self.auxcommands["select"].selectfunction("HpeServerBootSettings.")
|
||||
bootsettings = self.auxcommands["get"].getworkerfunction(
|
||||
"PersistentBootConfigOrder", options, results=True, uselist=True
|
||||
)
|
||||
|
||||
if not args:
|
||||
if not options.json:
|
||||
self.print_out_boot_order(
|
||||
bootsettings,
|
||||
onetimebootsettings,
|
||||
uefionetimebootsettings,
|
||||
bootmode,
|
||||
bootsources,
|
||||
bootstatus,
|
||||
targetstatus,
|
||||
)
|
||||
elif options.json:
|
||||
UI().print_out_json(bootsettings)
|
||||
elif len(args) == 1 and args[0][0] == "[":
|
||||
bootlist = args[0][1:-1].split(",")
|
||||
currentlist = bootsettings[0]["PersistentBootConfigOrder"]
|
||||
|
||||
if not isinstance(currentlist, list):
|
||||
templist = ast.literal_eval(currentlist[1:-1])
|
||||
currentlist = [n.strip() for n in templist]
|
||||
|
||||
removallist = copy.deepcopy(currentlist)
|
||||
|
||||
if len(bootlist) > len(currentlist):
|
||||
raise InvalidCommandLineError("Number of entries is greater than the current boot order length.")
|
||||
else:
|
||||
newlist = "["
|
||||
|
||||
for value, _ in enumerate(bootlist):
|
||||
try:
|
||||
newlist += currentlist[int(bootlist[value]) - 1]
|
||||
except:
|
||||
raise InvalidCommandLineError(
|
||||
"Invalid entry "
|
||||
"number passed to bootorder. Please \n"
|
||||
" run bootorder without arguments"
|
||||
" for possible boot \n order numbers. "
|
||||
)
|
||||
|
||||
removallist.remove(currentlist[int(bootlist[value]) - 1])
|
||||
|
||||
if removallist:
|
||||
newlist += ","
|
||||
|
||||
if not removallist:
|
||||
newlist += "]"
|
||||
else:
|
||||
for value, _ in enumerate(removallist):
|
||||
newlist += removallist[value]
|
||||
|
||||
if not value == len(removallist) - 1:
|
||||
newlist += ","
|
||||
|
||||
newlist += "]"
|
||||
|
||||
if options.biospassword:
|
||||
newlist += " --biospassword " + options.biospassword
|
||||
|
||||
if options.reboot:
|
||||
newlist += " --commit --reboot " + options.reboot
|
||||
elif options.commit:
|
||||
newlist += " --commit"
|
||||
|
||||
self.auxcommands["set"].run("PersistentBootConfigOrder=" + newlist)
|
||||
else:
|
||||
currlist = bootsettings[0]["PersistentBootConfigOrder"]
|
||||
if not isinstance(currlist, list):
|
||||
templist = ast.literal_eval(currlist[1:-1])
|
||||
currlist = [n.strip() for n in templist]
|
||||
remlist = copy.deepcopy(currlist)
|
||||
if len(args) > len(currlist):
|
||||
raise InvalidCommandLineError("Number of entries is " "greater than the current boot order length.")
|
||||
newlist = []
|
||||
for arg in args:
|
||||
argmatch = [val for val in remlist if fnmatch.fnmatch(val.lower(), arg.lower())]
|
||||
if not argmatch and not options.ime:
|
||||
raise InvalidCommandLineError(
|
||||
"Invalid entry passed: "
|
||||
"{0}. Please run bootorder to check for possible "
|
||||
"values and reevaluate.\n".format(arg)
|
||||
)
|
||||
if argmatch:
|
||||
newlist.extend(argmatch)
|
||||
_ = [remlist.remove(val) for val in newlist if val in remlist]
|
||||
newlist.extend(remlist)
|
||||
strlist = "["
|
||||
concatlist = reduce((lambda x, y: x + "," + y), newlist)
|
||||
strlist = strlist + concatlist + "]"
|
||||
|
||||
if options.biospassword:
|
||||
strlist += " --biospassword " + options.biospassword
|
||||
if options.reboot:
|
||||
strlist += " --commit --reboot " + options.reboot
|
||||
elif options.commit:
|
||||
strlist += " --commit"
|
||||
self.auxcommands["set"].run("PersistentBootConfigOrder=" + strlist)
|
||||
else:
|
||||
if options.onetimeboot is not None:
|
||||
entry = options.onetimeboot
|
||||
|
||||
if not bootstatus[0]["Boot"]["BootSourceOverrideEnabled"] == "Once":
|
||||
bootoverride = " Boot/BootSourceOverrideEnabled=Once"
|
||||
elif options.continuousboot is not None:
|
||||
entry = options.continuousboot
|
||||
|
||||
if not bootstatus[0]["Boot"]["BootSourceOverrideEnabled"] == "Continuous":
|
||||
bootoverride = " Boot/BootSourceOverrideEnabled=Continuous"
|
||||
else:
|
||||
entry = "JacksBootOption"
|
||||
if not bootstatus[0]["Boot"]["BootSourceOverrideEnabled"] == "Disabled":
|
||||
if currentsettings.dict["Boot"]["BootSourceOverrideEnabled"] == "Disabled":
|
||||
bootoverride = "Boot/BootSourceOverrideTarget=None" " Boot/BootSourceOverrideEnabled=Disabled"
|
||||
else:
|
||||
bootoverride = "Boot/BootSourceOverrideTarget=None"
|
||||
|
||||
newlist = ""
|
||||
|
||||
if entry.lower() in (
|
||||
item.lower()
|
||||
for item in onetimebootsettings[0]["Boot"][self.rdmc.app.typepath.defs.bootoverridetargettype]
|
||||
):
|
||||
if entry and isinstance(entry, six.string_types):
|
||||
entry = entry.upper()
|
||||
|
||||
entry = self.searchcasestring(
|
||||
entry,
|
||||
onetimebootsettings[0]["Boot"][self.rdmc.app.typepath.defs.bootoverridetargettype],
|
||||
)
|
||||
|
||||
if not entry == targetstatus[0]["Boot"]["BootSourceOverrideTarget"]:
|
||||
newlist += " Boot/BootSourceOverrideTarget=" + entry
|
||||
|
||||
if bootoverride:
|
||||
newlist += bootoverride
|
||||
|
||||
if options.biospassword and newlist:
|
||||
newlist += " --biospassword " + options.biospassword
|
||||
|
||||
if options.reboot and newlist:
|
||||
newlist += " --commit --reboot " + options.reboot
|
||||
elif options.commit and newlist:
|
||||
newlist += " --commit"
|
||||
|
||||
if newlist:
|
||||
self.auxcommands["set"].run(newlist)
|
||||
else:
|
||||
raise InvalidOrNothingChangedSettingsError("Entry is the current boot setting.")
|
||||
elif (
|
||||
uefionetimebootsettings
|
||||
and uefionetimebootsettings["Boot"]["UefiTargetBootSourceOverrideSupported"]
|
||||
and entry in (item for item in uefionetimebootsettings["Boot"]["UefiTargetBootSourceOverrideSupported"])
|
||||
):
|
||||
if entry and isinstance(entry, six.string_types):
|
||||
entry = entry.upper()
|
||||
|
||||
entry = self.searchcasestring(
|
||||
entry,
|
||||
uefionetimebootsettings["Boot"]["UefiTargetBootSourceOverrideSupported"],
|
||||
)
|
||||
try:
|
||||
# gen10
|
||||
allowable_vals = next(
|
||||
iter(
|
||||
self.auxcommands["get"].getworkerfunction(
|
||||
["Boot/UefiTargetBootSourceOverride@Redfish.AllowableValues"],
|
||||
options,
|
||||
results=True,
|
||||
uselist=True,
|
||||
)
|
||||
),
|
||||
{},
|
||||
)["Boot"]["UefiTargetBootSourceOverride@Redfish.AllowableValues"]
|
||||
for source in bootsources:
|
||||
if source["StructuredBootString"].upper() == entry.upper():
|
||||
for val in allowable_vals:
|
||||
if "UEFIDevicePath" in source and source["UEFIDevicePath"].endswith(val):
|
||||
entry = val
|
||||
break
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not entry == uefitargetstatus["Boot"]["UefiTargetBootSourceOverride"]:
|
||||
newlist += " Boot/UefiTargetBootSourceOverride=" + entry
|
||||
elif not targetstatus["Boot"]["BootSourceOverrideTarget"] == "UefiTarget":
|
||||
newlist += " Boot/BootSourceOverrideTarget=UefiTarget"
|
||||
|
||||
if bootoverride:
|
||||
if self.rdmc.app.typepath.defs.isgen9 and newlist:
|
||||
if not bootoverride.split("=")[-1] == bootstatus["Boot"]["BootSourceOverrideEnabled"]:
|
||||
# Preemptively set UefiTargetBootSourceOverride so iLO 4 doesn't complain
|
||||
self.rdmc.app.patch_handler(
|
||||
self.rdmc.app.typepath.defs.systempath,
|
||||
{"Boot": {"UefiTargetBootSourceOverride": entry}},
|
||||
silent=True,
|
||||
service=True,
|
||||
)
|
||||
self.rdmc.app.select(selector=self.rdmc.app.selector, path_refresh=True)
|
||||
newlist = ""
|
||||
newlist += bootoverride
|
||||
else:
|
||||
newlist += bootoverride
|
||||
|
||||
if options.reboot and newlist:
|
||||
newlist += " --commit --reboot " + options.reboot
|
||||
elif options.commit and newlist:
|
||||
newlist += " --commit"
|
||||
|
||||
if newlist:
|
||||
try:
|
||||
self.auxcommands["set"].run(newlist)
|
||||
except InvalidOrNothingChangedSettingsError:
|
||||
if self.rdmc.app.typepath.defs.isgen9:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
raise InvalidOrNothingChangedSettingsError("Entry is the " "current boot setting.\n")
|
||||
elif options.disablebootflag:
|
||||
if bootoverride:
|
||||
newlist += bootoverride
|
||||
|
||||
if options.reboot:
|
||||
newlist += " --commit --reboot " + options.reboot
|
||||
elif options.commit and newlist:
|
||||
newlist += " --commit"
|
||||
|
||||
if newlist:
|
||||
self.auxcommands["set"].run(newlist)
|
||||
else:
|
||||
raise InvalidOrNothingChangedSettingsError("Entry is the " "current boot setting.\n")
|
||||
else:
|
||||
raise InvalidCommandLineError(
|
||||
"Invalid entry passed for one"
|
||||
" time boot. Please run boot \n order without"
|
||||
" arguments to view available options.\n"
|
||||
)
|
||||
|
||||
self.cmdbase.logout_routine(self, options)
|
||||
|
||||
# Return code
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
def searchcasestring(self, entry, content):
|
||||
"""Helper function for retrieving correct case for value
|
||||
|
||||
:param entry: entry to correlate case
|
||||
:type entry: string.
|
||||
:param content: list of items
|
||||
:type content: list.
|
||||
"""
|
||||
for item in content:
|
||||
if entry.upper() == item.upper():
|
||||
return item
|
||||
|
||||
def secureboothelper(self, securebootoption):
|
||||
"""Helper function for secure boot function
|
||||
|
||||
:param securebootoption: option passed in for secure boot
|
||||
:type securebootoption: string.
|
||||
"""
|
||||
actionlist = ["defaultkeys", "deletekeys", "deletepk"]
|
||||
|
||||
if not securebootoption.lower() in actionlist:
|
||||
raise InvalidCommandLineError("%s is not a valid option for " "the securebootkeys flag." % securebootoption)
|
||||
|
||||
if securebootoption == actionlist[0]:
|
||||
action = "ResetAllKeysToDefault"
|
||||
elif securebootoption == actionlist[1]:
|
||||
action = "DeleteAllKeys"
|
||||
elif securebootoption == actionlist[2]:
|
||||
action = "DeletePK"
|
||||
|
||||
results = self.rdmc.app.select(selector=self.rdmc.app.typepath.defs.hpsecureboot)
|
||||
|
||||
try:
|
||||
results = results[0]
|
||||
except:
|
||||
pass
|
||||
|
||||
if results:
|
||||
path = results.resp.request.path
|
||||
results = results.resp.dict
|
||||
|
||||
try:
|
||||
for item in results["Actions"]:
|
||||
if "ResetKeys" in item:
|
||||
path = results["Actions"][item]["target"]
|
||||
break
|
||||
|
||||
body = {"ResetKeysType": action}
|
||||
self.rdmc.app.post_handler(path, body)
|
||||
except:
|
||||
if securebootoption == actionlist[0]:
|
||||
self.auxcommands["select"].selectfunction(self.rdmc.app.typepath.defs.hpsecureboot)
|
||||
self.auxcommands["set"].run("ResetToDefaultKeys=True --commit")
|
||||
elif securebootoption == actionlist[1]:
|
||||
self.auxcommands["select"].selectfunction(self.rdmc.app.typepath.defs.hpsecureboot)
|
||||
self.auxcommands["set"].run("ResetAllKeys=True --commit")
|
||||
else:
|
||||
self.rdmc.ui.warn("DeletePK option is not available on Gen9.\n")
|
||||
|
||||
def print_out_boot_order(
|
||||
self,
|
||||
content,
|
||||
onetimecontent,
|
||||
uefionetimecontent,
|
||||
bootmode,
|
||||
bootsources,
|
||||
bootstatus,
|
||||
targetstatus,
|
||||
):
|
||||
"""Convert content to human readable and print out to std.out
|
||||
|
||||
:param content: current content
|
||||
:type content: string.
|
||||
:param onetimecontent: list of one time boot entries
|
||||
:type onetimecontent: list.
|
||||
:param uefionetimecontent: list of uefi one time boot entries
|
||||
:type uefionetimecontent: list.
|
||||
:param bootmode: current system boot mode
|
||||
:type bootmode: string.
|
||||
:param bootsources: current systems boot sources
|
||||
:type bootsources: list.
|
||||
"""
|
||||
if content is None:
|
||||
raise BootOrderMissingEntriesError("No entries found in " "current boot order.\n\n")
|
||||
else:
|
||||
self.print_boot_helper(content[0], "\nCurrent Persistent Boot " "Order:", bootsources=bootsources)
|
||||
|
||||
bootstatusval = bootstatus[0]["Boot"]["BootSourceOverrideEnabled"]
|
||||
boottoval = targetstatus[0]["Boot"]["BootSourceOverrideTarget"]
|
||||
if bootstatusval == "Continuous":
|
||||
self.rdmc.ui.printer("Current continuous boot: {0}\n\n".format(boottoval))
|
||||
elif bootstatusval == "Once":
|
||||
self.rdmc.ui.printer("Current one time boot: {0}\n\n".format(boottoval))
|
||||
|
||||
if onetimecontent is None:
|
||||
raise BootOrderMissingEntriesError("No entries found for one time boot options.\n\n")
|
||||
else:
|
||||
self.print_boot_helper(onetimecontent[0]["Boot"], "Continuous and one time boot options:")
|
||||
|
||||
if bootmode and any([bootmode[0].get(boot, None) == "Uefi" for boot in bootmode[0]]):
|
||||
if uefionetimecontent is None:
|
||||
self.rdmc.ui.printer("Continuous and one time boot uefi options:\n")
|
||||
self.rdmc.ui.printer(
|
||||
"No entries found for one-time UEFI options or boot source mode " "is not set to UEFI."
|
||||
)
|
||||
else:
|
||||
if isinstance(uefionetimecontent, dict):
|
||||
self.print_boot_helper(
|
||||
uefionetimecontent["Boot"],
|
||||
"Continuous and one time boot uefi options:",
|
||||
bootsources=bootsources,
|
||||
)
|
||||
else:
|
||||
self.print_boot_helper(
|
||||
uefionetimecontent[0]["Boot"],
|
||||
"Continuous and one time boot uefi options:",
|
||||
bootsources=bootsources,
|
||||
)
|
||||
|
||||
def print_boot_helper(self, content, outstring, indent=0, bootsources=None):
|
||||
"""Print boot helper
|
||||
|
||||
:param content: current content
|
||||
:type content: string.
|
||||
:param outstring: output string
|
||||
:type outstring: string.
|
||||
:param indent: indent format
|
||||
:type indent: string.
|
||||
:param bootsources: current systems boot sources
|
||||
:type bootsources: list.
|
||||
"""
|
||||
for _, value in list(content.items()):
|
||||
self.rdmc.ui.printer("\t" * indent + outstring)
|
||||
|
||||
if isinstance(value, list):
|
||||
count = 1
|
||||
|
||||
for item in value:
|
||||
self.rdmc.ui.printer("\n")
|
||||
|
||||
if not item:
|
||||
item = str("null")
|
||||
|
||||
# if isinstance(item, six.string_types):
|
||||
bootstring = False
|
||||
try:
|
||||
for source in bootsources:
|
||||
if item == source["StructuredBootString"]:
|
||||
self.rdmc.ui.printer(
|
||||
"\t" * indent
|
||||
+ str(count)
|
||||
+ ". "
|
||||
+ str(item)
|
||||
+ " ("
|
||||
+ str(source["BootString"])
|
||||
+ ")"
|
||||
)
|
||||
bootstring = True
|
||||
break
|
||||
|
||||
if not bootstring:
|
||||
self.rdmc.ui.printer("\t" * indent + str(count) + ". " + str(item))
|
||||
except:
|
||||
self.rdmc.ui.printer("\t" * indent + str(count) + ". " + str(item))
|
||||
|
||||
count += 1
|
||||
# else:
|
||||
# self.print_boot_helper(item, indent+1)
|
||||
|
||||
self.rdmc.ui.printer("\n\n")
|
||||
|
||||
def bootordervalidation(self, options):
|
||||
"""Boot order method validation function
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
"""
|
||||
inputline = list()
|
||||
|
||||
if self.rdmc.config.commit.lower() == "true":
|
||||
options.commit = True
|
||||
|
||||
self.cmdbase.login_select_validation(self, options)
|
||||
|
||||
if inputline:
|
||||
self.lobobj.loginfunction(inputline)
|
||||
|
||||
if options.encode:
|
||||
options.biospassword = Encryption.decode_credentials(options.biospassword)
|
||||
if isinstance(options.biospassword, bytes):
|
||||
options.biospassword = options.biospassword.decode("utf-8")
|
||||
|
||||
@staticmethod
|
||||
def options_argument_group(parser):
|
||||
"""Additional argument
|
||||
|
||||
:param parser: The parser to add the removeprivs option group to
|
||||
:type parser: ArgumentParser/OptionParser
|
||||
"""
|
||||
|
||||
parser.add_argument_group(
|
||||
"GLOBAL OPTION:",
|
||||
"Option(s) are available " "for all arguments within the scope of this command.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-j",
|
||||
"--json",
|
||||
dest="json",
|
||||
action="store_true",
|
||||
help="Optionally include this flag if you wish to change the"
|
||||
" displayed output to JSON format. Preserving the JSON data"
|
||||
" structure makes the information easier to parse.",
|
||||
default=False,
|
||||
)
|
||||
|
||||
def definearguments(self, customparser):
|
||||
"""Wrapper function for new command main function
|
||||
|
||||
:param customparser: command line input
|
||||
:type customparser: parser.
|
||||
"""
|
||||
if not customparser:
|
||||
return
|
||||
|
||||
self.cmdbase.add_login_arguments_group(customparser)
|
||||
self.options_argument_group(customparser)
|
||||
|
||||
customparser.add_argument(
|
||||
"--onetimeboot",
|
||||
dest="onetimeboot",
|
||||
help="Use this flag to configure a one-time boot option."
|
||||
" Using this flag will prioritize the provided boot source"
|
||||
" only on the very next time the server is booted.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--continuousboot",
|
||||
dest="continuousboot",
|
||||
help="Use this flag to enable a continuous boot option. Using"
|
||||
" this flag will cause the system to boot to the selected"
|
||||
" device every time the system boots.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--disablebootflag",
|
||||
dest="disablebootflag",
|
||||
action="store_true",
|
||||
help="Use this to disable either continuous or one-time boot modes.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--securebootkeys",
|
||||
dest="secureboot",
|
||||
help="Use this flag to perform actions on secure boot keys."
|
||||
"Possible values include defaultkeys: resets all keys to default,"
|
||||
"deletekeys: deletes all keys, deletepk: deletes all product keys.",
|
||||
default=False,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--commit",
|
||||
dest="commit",
|
||||
action="store_true",
|
||||
help="Use this flag when you are ready to commit all pending"
|
||||
" changes. Note that some changes made in this way will be updated"
|
||||
" instantly, while others will be reflected the next time the"
|
||||
" server is started.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--reboot",
|
||||
dest="reboot",
|
||||
help="Use this flag to perform a reboot command function after"
|
||||
" completion of operations. For help with parameters and"
|
||||
" descriptions regarding the reboot flag, run help reboot.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--ignorematcherror",
|
||||
dest="ime",
|
||||
action="store_true",
|
||||
help="Use this flag when you want to run multiple matches and "
|
||||
"not throw an error in case there are no matches found for given "
|
||||
"expression.",
|
||||
default=None,
|
||||
)
|
||||
+978
@@ -0,0 +1,978 @@
|
||||
###
|
||||
# Copyright 2016-2021 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""IscsiConfig Command for rdmc"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
|
||||
import redfish.ris
|
||||
|
||||
try:
|
||||
from rdmc_helper import (
|
||||
BootOrderMissingEntriesError,
|
||||
Encryption,
|
||||
InvalidCommandLineError,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
NicMissingOrConfigurationError,
|
||||
ReturnCodes,
|
||||
)
|
||||
except:
|
||||
from ilorest.rdmc_helper import (
|
||||
BootOrderMissingEntriesError,
|
||||
Encryption,
|
||||
InvalidCommandLineError,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
NicMissingOrConfigurationError,
|
||||
ReturnCodes,
|
||||
)
|
||||
|
||||
|
||||
class IscsiConfigCommand:
|
||||
"""Changes the iscsi configuration for the server that is currently logged in"""
|
||||
|
||||
def __init__(self):
|
||||
self.ident = {
|
||||
"name": "iscsiconfig",
|
||||
"usage": None,
|
||||
"description": "Run without"
|
||||
" arguments for available NIC sources for iSCSI"
|
||||
" configuration.\n\texample: iscsiconfig\n\n\tDisplay"
|
||||
" the current iSCSI configuration:\n\texample: "
|
||||
"iscsiconfig --list\n\n\tSaving current iSCSI "
|
||||
"configuration to a file:\n\texample: iscsiconfig "
|
||||
"--list -f output.txt\n\n\tLoading iSCSI "
|
||||
"configurations from a file:\n\texample: iscsiconfig "
|
||||
"--modify output.txt\n\n\tIn order to add a NIC "
|
||||
'source to an iSCSI boot attempt you must run \n\t"'
|
||||
'iscsiconfig" without any paramters. This will '
|
||||
"display a list of NIC\n\tsources which are currently"
|
||||
" present in the system.\n\tAdding an iSCSI boot "
|
||||
"attempt:\n\texample: iscsiconfig --add 1\n\n\tIn "
|
||||
"order to delete an iSCSI boot attempt you must run"
|
||||
'\n\t"iscsiconfig --list" to view the currently '
|
||||
"configured attempts.\n\tOnce you find the attempt "
|
||||
"you want to delete simply pass the attempt\n\tnumber"
|
||||
" to the iSCSI delete function.\n\tDeleting an iSCSI "
|
||||
"boot attempt:\n\texample: iscsiconfig --delete 1",
|
||||
"summary": "Displays and configures the current iscsi settings.",
|
||||
"aliases": [],
|
||||
"auxcommands": [
|
||||
"GetCommand",
|
||||
"SetCommand",
|
||||
"SelectCommand",
|
||||
"RebootCommand",
|
||||
"LogoutCommand",
|
||||
],
|
||||
}
|
||||
self.cmdbase = None
|
||||
self.rdmc = None
|
||||
self.auxcommands = dict()
|
||||
|
||||
def run(self, line, help_disp=False):
|
||||
"""Main iscsi configuration worker function
|
||||
|
||||
:param line: string of arguments passed in
|
||||
:type line: str.
|
||||
"""
|
||||
if help_disp:
|
||||
self.parser.print_help()
|
||||
return ReturnCodes.SUCCESS
|
||||
try:
|
||||
(options, args) = self.rdmc.rdmc_parse_arglist(self, line)
|
||||
except (InvalidCommandLineErrorOPTS, SystemExit):
|
||||
if ("-h" in line) or ("--help" in line):
|
||||
return ReturnCodes.SUCCESS
|
||||
else:
|
||||
raise InvalidCommandLineErrorOPTS("")
|
||||
|
||||
self.iscsiconfigurationvalidation(options)
|
||||
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
iscsipath = self.gencompatpaths(selector="HpeiSCSISoftwareInitiator.", rel=False)
|
||||
if "/settings" not in iscsipath:
|
||||
iscsisettingspath = iscsipath + "settings"
|
||||
else:
|
||||
iscsisettingspath = iscsipath
|
||||
bootpath = self.gencompatpaths(selector="HpeServerBootSettings.")
|
||||
bootpath = bootpath.replace("/settings", "")
|
||||
else:
|
||||
# TODO: update gencompats to handle the nesting of these links within the gen 9 version.
|
||||
if self.rdmc.app.typepath.defs.biospath[-1] == "/":
|
||||
iscsipath = self.rdmc.app.typepath.defs.biospath + "iScsi/"
|
||||
iscsisettingspath = self.rdmc.app.typepath.defs.biospath + "iScsi/settings/"
|
||||
bootpath = self.rdmc.app.typepath.defs.biospath + "Boot/"
|
||||
else:
|
||||
iscsipath = self.rdmc.app.typepath.defs.biospath + "/iScsi"
|
||||
iscsisettingspath = self.rdmc.app.typepath.defs.biospath + "/iScsi/settings"
|
||||
bootpath = self.rdmc.app.typepath.defs.biospath + "/Boot"
|
||||
|
||||
if options.list:
|
||||
self.listoptionhelper(options, iscsipath, iscsisettingspath, bootpath)
|
||||
elif options.modify:
|
||||
self.modifyoptionhelper(options, iscsisettingspath)
|
||||
elif options.add:
|
||||
self.addoptionhelper(options, iscsipath, iscsisettingspath, bootpath)
|
||||
elif options.delete:
|
||||
self.deleteoptionhelper(options, iscsisettingspath)
|
||||
elif not args:
|
||||
self.defaultsoptionhelper(options, iscsipath, bootpath)
|
||||
else:
|
||||
if len(args) < 2:
|
||||
self.iscsiconfigurationvalidation(options)
|
||||
else:
|
||||
raise InvalidCommandLineError(
|
||||
"Invalid number of parameters. " "Iscsi configuration takes a maximum of 1 parameter."
|
||||
)
|
||||
|
||||
if options.reboot:
|
||||
self.auxcommands["reboot"].run(options.reboot)
|
||||
|
||||
self.cmdbase.logout_routine(self, options)
|
||||
# Return code
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
def gencompatpaths(self, selector=None, rel=False):
|
||||
"""Helper function for finding gen compatible paths
|
||||
|
||||
:param selector: the type selection for the get operation
|
||||
:type selector: str.
|
||||
:param rel: flag to tell select function to reload selected instance
|
||||
:type rel: boolean.
|
||||
:returns: returns urls
|
||||
"""
|
||||
|
||||
self.rdmc.app.select(selector=selector, path_refresh=rel)
|
||||
props = self.rdmc.app.getprops(skipnonsetting=False)
|
||||
for prop in props:
|
||||
name = prop.get("Name")
|
||||
if "current" in name.lower() or "pending" in name.lower():
|
||||
try:
|
||||
path = prop.get("@odata.id")
|
||||
except:
|
||||
self.rdmc.ui.error("URI path could not be found.")
|
||||
return path
|
||||
|
||||
def get_enabled_only(self):
|
||||
enable_disable = dict()
|
||||
final_enabled_list = list()
|
||||
|
||||
bios = "/redfish/v1/systems/1/bios/"
|
||||
bios_dict = self.rdmc.app.get_handler(bios, silent=True, service=True).dict
|
||||
if "Attributes" in bios_dict:
|
||||
bios_dict_attributes = bios_dict["Attributes"].items()
|
||||
else:
|
||||
bios_dict_attributes = bios_dict.items()
|
||||
for attr, val in bios_dict_attributes:
|
||||
if "NetworkBoot" in str(val):
|
||||
enable_disable[attr] = val
|
||||
# Enabled NIC only listing
|
||||
for k, v in enable_disable.items():
|
||||
final_enabled_list.append(k)
|
||||
|
||||
return final_enabled_list
|
||||
|
||||
def addoptionhelper(self, options, iscsipath, iscsisettingspath, bootpath):
|
||||
"""Helper function to add option for iscsi
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param iscsipath: current iscsi path
|
||||
:type iscsipath: str.
|
||||
:param iscsisettingspath: current iscsi settings path
|
||||
:type iscsisettingspath: str.
|
||||
:param bootpath: current boot path
|
||||
:type bootpath: str.
|
||||
"""
|
||||
devicealloc = list()
|
||||
self.auxcommands["select"].selectfunction("HpeBiosMapping.")
|
||||
pcisettingsmap = self.auxcommands["get"].getworkerfunction(
|
||||
"BiosPciSettingsMappings", options, results=True, uselist=True
|
||||
)
|
||||
|
||||
for item in pcisettingsmap[0]["BiosPciSettingsMappings"]:
|
||||
if "Associations" in item:
|
||||
if (
|
||||
"EmbNicEnable" in item["Associations"]
|
||||
or "EmbNicConfig" in item["Associations"]
|
||||
or "OcpAEnable" in item["Associations"]
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
|
||||
if (
|
||||
re.match("FlexLom[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("PciSlot[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("Slot[0-9]+NicBoot[0-9]+", item["Associations"][0])
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
|
||||
foundlocation = False
|
||||
iscsibootsources = self.rawdatahandler(action="GET", silent=True, jsonflag=True, path=iscsisettingspath)
|
||||
count = 0
|
||||
attemptinstancenumber = self.bootattemptcounter(iscsibootsources[self.rdmc.app.typepath.defs.iscsisource])
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
newpcilist = []
|
||||
self.auxcommands["select"].selectfunction("HpeServerPciDeviceCollection")
|
||||
pcideviceslist = next(
|
||||
iter(self.auxcommands["get"].getworkerfunction("Members", options, results=True, uselist=False)),
|
||||
None,
|
||||
)
|
||||
for device in pcideviceslist["Members"]:
|
||||
newpcilist.append(self.rdmc.app.get_handler(device["@odata.id"], silent=True).dict)
|
||||
pcideviceslist = newpcilist
|
||||
else:
|
||||
self.auxcommands["select"].selectfunction(["Collection."])
|
||||
pcideviceslist = next(
|
||||
iter(
|
||||
self.auxcommands["get"].getworkerfunction(
|
||||
"Items",
|
||||
options,
|
||||
results=True,
|
||||
uselist=False,
|
||||
filtervals=("MemberType", "HpServerPciDevice.*"),
|
||||
)
|
||||
),
|
||||
None,
|
||||
)["Items"]
|
||||
|
||||
self.pcidevicehelper(devicealloc, iscsipath, bootpath, pcideviceslist)
|
||||
|
||||
devicealloc_final = self.make_final_list(devicealloc, pcideviceslist)
|
||||
|
||||
print_flag = False
|
||||
iscsi_list = self.listoptionhelper(options, iscsipath, iscsisettingspath, bootpath, print_flag)
|
||||
refined_list = list()
|
||||
for s in iscsi_list:
|
||||
for key, val in s.items():
|
||||
if key != "Not Added":
|
||||
for k, v in val.items():
|
||||
refined_list.append(v["iSCSINicSource"])
|
||||
enabled_only_bootsource = self.get_enabled_only()
|
||||
refined_devicealloc = list()
|
||||
for d in devicealloc:
|
||||
if "PreBootNetwork" in d["Associations"][0]:
|
||||
nic = d["Associations"][1]
|
||||
else:
|
||||
nic = d["Associations"][0]
|
||||
if "Storage" in nic:
|
||||
continue
|
||||
if nic in enabled_only_bootsource:
|
||||
refined_devicealloc.append(d)
|
||||
|
||||
for item in iscsibootsources[self.rdmc.app.typepath.defs.iscsisource]:
|
||||
try:
|
||||
if not item[self.rdmc.app.typepath.defs.iscsiattemptinstance]:
|
||||
nicsourcedata = refined_devicealloc[int(options.add) - 1]["Associations"]
|
||||
if "PreBootNetwork" in nicsourcedata[0]:
|
||||
nic_getting_added = nicsourcedata[1]
|
||||
else:
|
||||
nic_getting_added = nicsourcedata[0]
|
||||
if nic_getting_added in refined_list:
|
||||
self.rdmc.ui.printer("Warning: This NIC is already added to existing attempt\n")
|
||||
iscsibootsources[self.rdmc.app.typepath.defs.iscsisource][count]["iSCSINicSource"] = (
|
||||
nicsourcedata[1] if isinstance(nicsourcedata[0], dict) else nicsourcedata[0]
|
||||
)
|
||||
|
||||
iscsibootsources[self.rdmc.app.typepath.defs.iscsisource][count][
|
||||
self.rdmc.app.typepath.defs.iscsiattemptinstance
|
||||
] = attemptinstancenumber
|
||||
iscsibootsources[self.rdmc.app.typepath.defs.iscsisource][count][
|
||||
self.rdmc.app.typepath.defs.iscsiattemptname
|
||||
] = str(attemptinstancenumber)
|
||||
foundlocation = True
|
||||
break
|
||||
except Exception:
|
||||
raise NicMissingOrConfigurationError("Invalid input value for configuring NIC.")
|
||||
count += 1
|
||||
|
||||
if foundlocation:
|
||||
self.rdmc.app.patch_handler(
|
||||
iscsisettingspath,
|
||||
iscsibootsources,
|
||||
optionalpassword=options.biospassword,
|
||||
)
|
||||
else:
|
||||
raise NicMissingOrConfigurationError("Failed to add NIC. All NICs" " have already been configured.")
|
||||
|
||||
def make_final_list(self, devicealloc, pcideviceslist):
|
||||
final_devicealloc = []
|
||||
for item in devicealloc:
|
||||
if isinstance(item["Associations"][0], dict):
|
||||
listval = 1
|
||||
else:
|
||||
listval = 0
|
||||
if "Storage" not in item["Associations"][listval]:
|
||||
for pcidevice in pcideviceslist:
|
||||
# if item["CorrelatableID"] == pcidevice["UEFIDevicePath"]:
|
||||
final_devicealloc.append(item)
|
||||
return final_devicealloc
|
||||
|
||||
def bootattemptcounter(self, bootsources):
|
||||
"""Helper function to count the current boot entries for iscsi
|
||||
|
||||
:param bootsources: current iscsi boot sources
|
||||
:type bootsources: list.
|
||||
"""
|
||||
size = 0
|
||||
count = list()
|
||||
|
||||
for item in bootsources:
|
||||
size += 1
|
||||
|
||||
if item[self.rdmc.app.typepath.defs.iscsiattemptinstance]:
|
||||
count.append(int(item[self.rdmc.app.typepath.defs.iscsiattemptinstance]))
|
||||
|
||||
if size == len(count):
|
||||
raise NicMissingOrConfigurationError("Failed to add NIC. All " "NICs have already been configured.")
|
||||
|
||||
count.sort(key=None, reverse=False)
|
||||
|
||||
if len(count) > 0:
|
||||
iterate = 0
|
||||
|
||||
for i in range(1, size + 1, 1):
|
||||
if iterate < len(count) and i == count[iterate]:
|
||||
iterate += 1
|
||||
else:
|
||||
return iterate + 1
|
||||
else:
|
||||
return int(1)
|
||||
|
||||
def deleteoptionhelper(self, options, iscsisettingspath):
|
||||
"""Helper function to delete option for iscsi
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param iscsisettingspath: current iscsi settings path
|
||||
:type iscsisettingspath: string.
|
||||
"""
|
||||
patch = None
|
||||
|
||||
self.auxcommands["select"].selectfunction("HpBaseConfigs.")
|
||||
contents = self.rdmc.app.getprops(selector="BaseConfigs")
|
||||
|
||||
for content in contents:
|
||||
for key in content["BaseConfigs"][0]["default"]:
|
||||
if key == self.rdmc.app.typepath.defs.iscsisource:
|
||||
patch = content["BaseConfigs"][0]["default"][key]
|
||||
|
||||
if not patch:
|
||||
raise NicMissingOrConfigurationError("Could not access Base Configurations.")
|
||||
|
||||
self.validateinput(options=options, deleteoption=True)
|
||||
|
||||
foundlocation = False
|
||||
iscsibootsources = self.rawdatahandler(action="GET", silent=True, jsonflag=False, path=iscsisettingspath)
|
||||
holdetag = iscsibootsources.getheader("etag")
|
||||
iscsibootsources = json.loads(iscsibootsources.read)
|
||||
|
||||
try:
|
||||
count = 0
|
||||
for item in iscsibootsources[self.rdmc.app.typepath.defs.iscsisource]:
|
||||
if item[self.rdmc.app.typepath.defs.iscsiattemptinstance] == int(options.delete):
|
||||
iscsibootsources[self.rdmc.app.typepath.defs.iscsisource][count] = patch[count]
|
||||
foundlocation = True
|
||||
|
||||
count += 1
|
||||
except Exception:
|
||||
raise NicMissingOrConfigurationError(
|
||||
"The NIC targeted for delete" " does not exist. The request for " "delete could not be completed."
|
||||
)
|
||||
|
||||
if foundlocation:
|
||||
self.rdmc.app.put_handler(
|
||||
iscsisettingspath,
|
||||
iscsibootsources,
|
||||
optionalpassword=options.biospassword,
|
||||
headers={"if-Match": holdetag},
|
||||
)
|
||||
self.rdmc.app.get_handler(iscsisettingspath, silent=True)
|
||||
else:
|
||||
raise NicMissingOrConfigurationError("The given attempt instance does not exist.")
|
||||
|
||||
def listoptionhelper(self, options, iscsipath, iscsisettingspath, bootpath, print_flag=True):
|
||||
"""Helper function to list options for iscsi
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param iscsipath: current iscsi path
|
||||
:type iscsipath: str.
|
||||
:param iscsisettingspath: current iscsi settings path
|
||||
:type iscsisettingspath: str.
|
||||
:param bootpath: current boot path
|
||||
:type bootpath: str.
|
||||
"""
|
||||
self.auxcommands["select"].selectfunction("HpeBiosMapping.")
|
||||
pcisettingsmap = self.auxcommands["get"].getworkerfunction(
|
||||
"BiosPciSettingsMappings", options, results=True, uselist=True
|
||||
)
|
||||
|
||||
devicealloc = list()
|
||||
for item in pcisettingsmap[0]["BiosPciSettingsMappings"]:
|
||||
if "Associations" in item:
|
||||
if (
|
||||
"EmbNicEnable" in item["Associations"]
|
||||
or "EmbNicConfig" in item["Associations"]
|
||||
or "OcpAEnable" in item["Associations"]
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
|
||||
if (
|
||||
re.match("FlexLom[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("PciSlot[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("Slot[0-9]+NicBoot[0-9]+", item["Associations"][0])
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
newpcilist = []
|
||||
|
||||
self.auxcommands["select"].selectfunction("HpeServerPciDeviceCollection")
|
||||
pcideviceslist = next(
|
||||
iter(self.auxcommands["get"].getworkerfunction("Members", options, results=True, uselist=False)),
|
||||
None,
|
||||
)
|
||||
|
||||
for device in pcideviceslist["Members"]:
|
||||
newpcilist.append(self.rdmc.app.get_handler(device["@odata.id"], silent=True).dict)
|
||||
|
||||
pcideviceslist = newpcilist
|
||||
else:
|
||||
self.auxcommands["select"].selectfunction(["Collection."])
|
||||
pcideviceslist = next(
|
||||
iter(
|
||||
self.auxcommands["get"].getworkerfunction(
|
||||
"Items",
|
||||
options,
|
||||
results=True,
|
||||
uselist=False,
|
||||
filtervals=("MemberType", "HpServerPciDevice.*"),
|
||||
)
|
||||
),
|
||||
None,
|
||||
)["Items"]
|
||||
i = 0
|
||||
iscsibootsources = ""
|
||||
while i < 4:
|
||||
self.auxcommands["select"].selectfunction("HpiSCSISoftwareInitiator.")
|
||||
iscsibootsources = self.rawdatahandler(action="GET", silent=True, jsonflag=True, path=iscsisettingspath)
|
||||
if not ("error" in iscsibootsources):
|
||||
break
|
||||
time.sleep(10)
|
||||
i = i + 1
|
||||
self.rdmc.ui.printer("Retrying ...\n\n")
|
||||
structeredlist = list()
|
||||
|
||||
self.pcidevicehelper(devicealloc, iscsipath, bootpath, pcideviceslist)
|
||||
if not ("error" in iscsibootsources):
|
||||
total_attempts = []
|
||||
for item in iscsibootsources[self.rdmc.app.typepath.defs.iscsisource]:
|
||||
if item["iSCSINicSource"]:
|
||||
iscsi_attempt = item[self.rdmc.app.typepath.defs.iscsiattemptinstance]
|
||||
for device in devicealloc:
|
||||
it = device["CorrelatableID"].split(",")
|
||||
del it[-1]
|
||||
it = ",".join(it)
|
||||
listval = 0
|
||||
if not isinstance(device["Associations"][0], list):
|
||||
listval = 1 if isinstance(device["Associations"][0], dict) else 0
|
||||
|
||||
if item["iSCSINicSource"] == device["Associations"][listval]:
|
||||
for pcidevice in pcideviceslist:
|
||||
if "Storage" in pcidevice["DeviceType"]:
|
||||
continue
|
||||
pcid = pcidevice["UEFIDevicePath"].split(",")
|
||||
del pcid[-1]
|
||||
pcid = ",".join(pcid)
|
||||
# using total_attempts to avoid duplicate entries
|
||||
if (
|
||||
device["CorrelatableID"] == pcidevice["UEFIDevicePath"]
|
||||
or ("Embedded" not in pcidevice["DeviceType"] and (pcid == it))
|
||||
) and iscsi_attempt not in total_attempts:
|
||||
total_attempts.append(iscsi_attempt)
|
||||
inputstring = (
|
||||
pcidevice["DeviceType"]
|
||||
+ " "
|
||||
+ str(pcidevice["DeviceInstance"])
|
||||
+ " Port "
|
||||
+ str(device["Subinstance"])
|
||||
+ " : "
|
||||
+ pcidevice.get("Name", "").strip()
|
||||
)
|
||||
structeredlist.append({inputstring: {str("Attempt " + str(iscsi_attempt)): item}})
|
||||
|
||||
else:
|
||||
structeredlist.append({"Not Added": {}})
|
||||
|
||||
try:
|
||||
if iscsibootsources is None:
|
||||
raise BootOrderMissingEntriesError("No entries found for iscsi boot sources \n\n")
|
||||
elif "error" in iscsibootsources:
|
||||
raise BootOrderMissingEntriesError(
|
||||
"/redfish/v1/systems/1/bios/oem/hpe/iscsi/settings URI seems to be not reachable even after"
|
||||
" 4 retry attempts , kindly retry the command after some time \n\n"
|
||||
)
|
||||
elif not options.filename and print_flag:
|
||||
self.print_iscsi_config_helper(structeredlist, "Current iSCSI Attempts: \n")
|
||||
except Exception as excp:
|
||||
raise excp
|
||||
|
||||
if structeredlist is None:
|
||||
self.rdmc.ui.error("No entries found for iscsi boot sources.\n\n")
|
||||
elif options.filename:
|
||||
output = json.dumps(structeredlist, indent=2, cls=redfish.ris.JSONEncoder, sort_keys=True)
|
||||
filehndl = open(options.filename[0], "w")
|
||||
filehndl.write(output)
|
||||
filehndl.close()
|
||||
|
||||
self.rdmc.ui.printer("Results written out to '%s'\n" % options.filename[0])
|
||||
return structeredlist
|
||||
|
||||
def defaultsoptionhelper(self, options, iscsipath, bootpath):
|
||||
"""Helper function for default options for iscsi
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param iscsipath: current iscsi path
|
||||
:type iscsipath: str.
|
||||
:param bootpath: current boot path
|
||||
:type bootpath: str.
|
||||
"""
|
||||
self.auxcommands["select"].selectfunction("HpBiosMapping.")
|
||||
pcisettingsmap = self.auxcommands["get"].getworkerfunction(
|
||||
"BiosPciSettingsMappings", options, results=True, uselist=True
|
||||
)
|
||||
|
||||
devicealloc = list()
|
||||
for item in pcisettingsmap[0]["BiosPciSettingsMappings"]:
|
||||
if "Associations" in item:
|
||||
# self.rdmc.ui.printer("Assoc 1 : %s\n" % (item["Associations"]))
|
||||
# self.rdmc.ui.printer("Sub 1 : %s\n" % (item["Subinstances"]))
|
||||
if (
|
||||
"EmbNicEnable" in item["Associations"]
|
||||
or "EmbNicConfig" in item["Associations"]
|
||||
or "OcpAEnable" in item["Associations"]
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
|
||||
try:
|
||||
if (
|
||||
re.match("FlexLom[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("PciSlot[0-9]+Enable", item["Associations"][0])
|
||||
or re.match("Slot[0-9]+NicBoot[0-9]+", item["Associations"][0])
|
||||
):
|
||||
_ = [devicealloc.append(x) for x in item["Subinstances"]]
|
||||
except IndexError:
|
||||
pass
|
||||
# self.rdmc.ui.printer("Device alloc : %s\n" % devicealloc)
|
||||
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
newpcilist = []
|
||||
self.auxcommands["select"].selectfunction("HpeServerPciDeviceCollection")
|
||||
pcideviceslist = self.auxcommands["get"].getworkerfunction("Members", options, results=True, uselist=False)
|
||||
pcideviceslist = pcideviceslist[0]
|
||||
for device in pcideviceslist["Members"]:
|
||||
newpcilist.append(self.rdmc.app.get_handler(device["@odata.id"], silent=True).dict)
|
||||
pcideviceslist = newpcilist
|
||||
else:
|
||||
self.auxcommands["select"].selectfunction(["Collection."])
|
||||
pcideviceslist = self.auxcommands["get"].getworkerfunction(
|
||||
"Items",
|
||||
options,
|
||||
results=True,
|
||||
uselist=False,
|
||||
filtervals=("MemberType", "HpServerPciDevice.*"),
|
||||
)[0]["Items"]
|
||||
|
||||
self.auxcommands["select"].selectfunction(self.rdmc.app.typepath.defs.hpiscsisoftwareinitiatortype)
|
||||
iscsiinitiatorname = self.auxcommands["get"].getworkerfunction(
|
||||
"iSCSIInitiatorName", options, results=True, uselist=True
|
||||
)
|
||||
|
||||
disabledlist = self.pcidevicehelper(devicealloc, iscsipath, bootpath, pcideviceslist)
|
||||
|
||||
self.print_out_iscsi_configuration(iscsiinitiatorname[0], devicealloc, pcideviceslist)
|
||||
|
||||
if disabledlist:
|
||||
self.print_out_iscsi_configuration(iscsiinitiatorname[0], disabledlist, pcideviceslist, disabled=True)
|
||||
|
||||
def modifyoptionhelper(self, options, iscsisettingspath):
|
||||
"""Helper function to modify options for iscsi
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param iscsisettingspath: current iscsi settings path
|
||||
:type iscsisettingspath: str.
|
||||
"""
|
||||
try:
|
||||
inputfile = open(options.modify, "r")
|
||||
contentsholder = json.loads(inputfile.read())
|
||||
except Exception as excp:
|
||||
raise InvalidCommandLineError("%s" % excp)
|
||||
|
||||
iscsibootsources = self.rawdatahandler(action="GET", silent=True, jsonflag=True, path=iscsisettingspath)
|
||||
|
||||
count = 0
|
||||
resultsdict = list()
|
||||
|
||||
for item in contentsholder:
|
||||
for entry in item.values():
|
||||
enteredsection = False
|
||||
|
||||
for key, value in entry.items():
|
||||
enteredsection = True
|
||||
resultsdict.append(
|
||||
self.modifyfunctionhelper(
|
||||
key,
|
||||
value,
|
||||
iscsibootsources[self.rdmc.app.typepath.defs.iscsisource],
|
||||
)
|
||||
)
|
||||
|
||||
if not enteredsection:
|
||||
resultsdict.append(iscsibootsources[self.rdmc.app.typepath.defs.iscsisource][count])
|
||||
|
||||
count += 1
|
||||
|
||||
contentsholder = {self.rdmc.app.typepath.defs.iscsisource: resultsdict}
|
||||
|
||||
self.rdmc.app.patch_handler(iscsisettingspath, contentsholder, optionalpassword=options.biospassword)
|
||||
self.rdmc.app.get_handler(iscsisettingspath, silent=True)
|
||||
self.rdmc.ui.printer("Please reboot the server for changes to take effect\n")
|
||||
|
||||
def modifyfunctionhelper(self, key, value, bootsources):
|
||||
"""Helper function to modify the entries for iscsi
|
||||
|
||||
:param key: key to be used for attempt
|
||||
:type key: string.
|
||||
:param value: value to apply to attempt
|
||||
:type value: str.
|
||||
:param bootsources: current boot sources
|
||||
:type bootsources: list.
|
||||
"""
|
||||
foundoption = False
|
||||
|
||||
for bootsource in bootsources:
|
||||
if bootsource[self.rdmc.app.typepath.defs.iscsiattemptinstance] == int(key[-1:]):
|
||||
foundoption = True
|
||||
break
|
||||
else:
|
||||
return value
|
||||
if foundoption:
|
||||
return value
|
||||
|
||||
def pcidevicehelper(self, devicealloc, iscsipath, bootpath, pcideviceslist=None, options=None):
|
||||
"""Helper function to check for extra pci devices / identify disabled devices
|
||||
|
||||
:param devicealloc: list of devices allocated
|
||||
:type devicealloc: list.
|
||||
:param iscsipath: current iscsi path
|
||||
:type iscsipath: str.
|
||||
:param bootpath: current boot path
|
||||
:type bootpath: str.
|
||||
:param pcideviceslist: current pci device list
|
||||
:type pcideviceslist: list.
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
"""
|
||||
if not pcideviceslist:
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
newpcilist = []
|
||||
self.auxcommands["select"].selectfunction("HpeServerPciDeviceCollection")
|
||||
pcideviceslist = next(
|
||||
iter(self.auxcommands["get"].getworkerfunction("Members", options, results=True, uselist=False)),
|
||||
None,
|
||||
)
|
||||
|
||||
for device in pcideviceslist["Members"]:
|
||||
newpcilist.append(self.rdmc.app.get_handler(device["@odata.id"], silent=True).dict)
|
||||
|
||||
pcideviceslist = newpcilist
|
||||
else:
|
||||
self.auxcommands["select"].selectfunction(["Collection."])
|
||||
pcideviceslist = next(
|
||||
iter(
|
||||
self.auxcommands["get"].getworkerfunction(
|
||||
"Items",
|
||||
options,
|
||||
results=True,
|
||||
uselist=False,
|
||||
filtervals=("MemberType", "HpServerPciDevice.*"),
|
||||
)
|
||||
),
|
||||
None,
|
||||
)["Items"]
|
||||
try:
|
||||
self.rawdatahandler(action="GET", silent=True, jsonflag=True, path=iscsipath)["iSCSINicSources"]
|
||||
except:
|
||||
raise NicMissingOrConfigurationError("No iSCSI nic sources available.")
|
||||
|
||||
_ = [x["UEFIDevicePath"] for x in pcideviceslist]
|
||||
removal = list()
|
||||
|
||||
bios = self.rawdatahandler(action="GET", silent=True, jsonflag=True, path=bootpath)
|
||||
|
||||
for item in devicealloc:
|
||||
if isinstance(item["Associations"][0], dict):
|
||||
if "PreBootNetwork" in list(item["Associations"][0].keys()):
|
||||
if item["Associations"] and item["Associations"][0]["PreBootNetwork"] in list(bios.keys()):
|
||||
if bios[item["Associations"][0]["PreBootNetwork"]] == "Disabled":
|
||||
removal.append(item)
|
||||
else:
|
||||
if item["Associations"] and item["Associations"][0] in list(bios.keys()):
|
||||
if bios[item["Associations"][0]] == "Disabled":
|
||||
removal.append(item)
|
||||
|
||||
_ = [devicealloc.remove(x) for x in removal]
|
||||
|
||||
return removal
|
||||
|
||||
def print_out_iscsi_configuration(self, iscsiinitiatorname, devicealloc, pcideviceslist, disabled=False):
|
||||
"""Convert content to human readable and print out to std.out
|
||||
|
||||
:param iscsiinitiatorname: iscsi initiator name
|
||||
:type iscsiinitiatorname: str.
|
||||
:param devicealloc: list of devices allocated
|
||||
:type devicealloc: list.
|
||||
:param pcideviceslist: current pci device list
|
||||
:type pcideviceslist: list.
|
||||
:param disabled: command line options
|
||||
:type disabled: boolean.
|
||||
"""
|
||||
try:
|
||||
if iscsiinitiatorname is None:
|
||||
BootOrderMissingEntriesError("No entry found for the iscsi initiator name.\n\n")
|
||||
elif disabled:
|
||||
pass
|
||||
else:
|
||||
self.print_iscsi_config_helper(iscsiinitiatorname["iSCSIInitiatorName"], "\nIscsi Initiator Name: ")
|
||||
except Exception as excp:
|
||||
raise excp
|
||||
|
||||
try:
|
||||
final_device_list = list()
|
||||
enable_val = list()
|
||||
|
||||
bios = "/redfish/v1/systems/1/bios/"
|
||||
bios_dict = self.rdmc.app.get_handler(bios, silent=True, service=True).dict
|
||||
if "Attributes" in bios_dict:
|
||||
bios_dict_items = bios_dict["Attributes"].items()
|
||||
else:
|
||||
bios_dict_items = bios_dict.items()
|
||||
for attr, val in bios_dict_items:
|
||||
if "NetworkBoot" in str(val):
|
||||
enable_val.append(attr.lower().strip())
|
||||
|
||||
# before comparing with pcideviceslist filtering enabled nics only
|
||||
devicealloc = [
|
||||
val
|
||||
for val in devicealloc
|
||||
if (len(val["Associations"]) == 2 and val["Associations"][1].lower() in enable_val)
|
||||
]
|
||||
|
||||
if devicealloc and pcideviceslist:
|
||||
count = 0
|
||||
output_data = []
|
||||
for pcidevice in pcideviceslist:
|
||||
if "storage" in pcidevice["DeviceType"].lower():
|
||||
continue
|
||||
|
||||
pcid = pcidevice["UEFIDevicePath"].split(",")
|
||||
del pcid[-1]
|
||||
pcid = ",".join(pcid)
|
||||
|
||||
for item in devicealloc:
|
||||
it = item["CorrelatableID"].split(",")
|
||||
del it[-1]
|
||||
it = ",".join(it)
|
||||
|
||||
# Match the correlatable ID from the
|
||||
# PCI device & allocated device
|
||||
if pcid == it:
|
||||
# Format the device information
|
||||
device = (
|
||||
pcidevice["DeviceType"]
|
||||
+ " "
|
||||
+ str(pcidevice["DeviceInstance"])
|
||||
+ " Port "
|
||||
+ str(item["Subinstance"])
|
||||
)
|
||||
# final_device_list using to
|
||||
# avoid the duplicate entries
|
||||
if device not in final_device_list:
|
||||
final_device_list.append(device)
|
||||
# Add the device name or
|
||||
# structured name to the dictionary
|
||||
if "Name" not in pcidevice:
|
||||
name = pcidevice.get(
|
||||
"StructuredName",
|
||||
"",
|
||||
).strip()
|
||||
else:
|
||||
name = pcidevice.get("Name", "").strip()
|
||||
|
||||
count = count + 1
|
||||
output_data.append(f"{[count]} {device} : {name}\n")
|
||||
|
||||
if output_data:
|
||||
# display output data
|
||||
status = "Disabled" if disabled else "Available"
|
||||
self.rdmc.ui.printer(f"\n{status} iSCSI Boot Network Interfaces: \n")
|
||||
[self.rdmc.ui.printer(i) for i in output_data]
|
||||
print() # For a blank line, after the output
|
||||
else:
|
||||
self.rdmc.ui.printer("No iSCSI Boot Network Interfaces Available.\n\n")
|
||||
|
||||
else:
|
||||
raise BootOrderMissingEntriesError("No entries found for" " iscsi configurations devices.\n")
|
||||
except Exception as excp:
|
||||
raise excp
|
||||
|
||||
def print_iscsi_config_helper(self, content, outstring, indent=0):
|
||||
"""Print iscsi configuration helper
|
||||
|
||||
:param content: current content to be output
|
||||
:type content: string.
|
||||
:param outstring: current output string
|
||||
:type outstring: str.
|
||||
:param indent: current iscsi settings path
|
||||
:type indent: str.
|
||||
"""
|
||||
self.rdmc.ui.printer("\t" * indent + outstring)
|
||||
|
||||
if content:
|
||||
self.rdmc.ui.print_out_json(content)
|
||||
else:
|
||||
self.rdmc.ui.error("\t" * indent + "No entries currently configured.\n")
|
||||
|
||||
self.rdmc.ui.printer("\n\n")
|
||||
|
||||
def rawdatahandler(self, action="None", path=None, silent=True, jsonflag=False):
|
||||
"""Helper function to get and put the raw data
|
||||
|
||||
:param action: current rest action
|
||||
:type action: list.
|
||||
:param path: current path
|
||||
:type path: str.
|
||||
:param silent: flag to determine silent mode
|
||||
:type silent: boolean.
|
||||
:param jsonflag: flag to determine json output
|
||||
:type jsonflag: boolean.
|
||||
"""
|
||||
if action == "GET":
|
||||
rawdata = self.rdmc.app.get_handler(get_path=path, silent=silent)
|
||||
|
||||
if jsonflag is True:
|
||||
rawdata = json.loads(rawdata.read)
|
||||
|
||||
return rawdata
|
||||
|
||||
def validateinput(self, deviceallocsize=None, options=None, deleteoption=False):
|
||||
"""Helper function to validate that the input is correct
|
||||
|
||||
:param deviceallocsize: current device allocated size
|
||||
:type deviceallocsize: str.
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
:param deleteoption: flag to delete option
|
||||
:type deleteoption: boolean.
|
||||
"""
|
||||
if deviceallocsize:
|
||||
try:
|
||||
if int(options.add) - 1 >= deviceallocsize:
|
||||
raise NicMissingOrConfigurationError("Please verify the " "given input value for configuring NIC.")
|
||||
except Exception:
|
||||
raise NicMissingOrConfigurationError("Please verify the " "given input value for configuring NIC.")
|
||||
if deleteoption:
|
||||
try:
|
||||
if int(options.delete) == 0:
|
||||
raise NicMissingOrConfigurationError(
|
||||
"Invalid input value." "Please give valid attempt for instance values."
|
||||
)
|
||||
except Exception:
|
||||
raise NicMissingOrConfigurationError(
|
||||
"Invalid input value." "Please give valid attempt for instance values."
|
||||
)
|
||||
|
||||
def iscsiconfigurationvalidation(self, options):
|
||||
"""iscsi configuration method validation function
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
"""
|
||||
self.cmdbase.login_select_validation(self, options)
|
||||
|
||||
if options.encode:
|
||||
options.biospassword = Encryption.decode_credentials(options.biospassword)
|
||||
if isinstance(options.biospassword, bytes):
|
||||
options.biospassword = options.biospassword.decode("utf-8")
|
||||
|
||||
def definearguments(self, customparser):
|
||||
"""Wrapper function for new command main function
|
||||
|
||||
:param customparser: command line input
|
||||
:type customparser: parser.
|
||||
"""
|
||||
if not customparser:
|
||||
return
|
||||
|
||||
self.cmdbase.add_login_arguments_group(customparser)
|
||||
|
||||
customparser.add_argument(
|
||||
"-f",
|
||||
"--filename",
|
||||
dest="filename",
|
||||
help="Use this flag if you wish to use a different"
|
||||
" filename than the default one. The default filename is"
|
||||
" ilorest.json.",
|
||||
action="append",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--add",
|
||||
dest="add",
|
||||
help="Use this iSCSI configuration option to add an iSCSI" " configuration option.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--delete",
|
||||
dest="delete",
|
||||
help="Use this iSCSI configuration option to delete an iSCSI" " configuration option.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--modify",
|
||||
dest="modify",
|
||||
help="Use this iSCSI configuration option to modify an iSCSI" " configuration option.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--list",
|
||||
dest="list",
|
||||
action="store_true",
|
||||
help="Use this iSCSI configuration option to list the details" " of the different iSCSI configurations.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--reboot",
|
||||
dest="reboot",
|
||||
help="Use this flag to perform a reboot command function after"
|
||||
" completion of operations. For help with parameters and"
|
||||
" descriptions regarding the reboot flag, run help reboot.",
|
||||
default=None,
|
||||
)
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
###
|
||||
# Copyright 2016-2021 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""SetPassword Command for rdmc"""
|
||||
|
||||
try:
|
||||
from rdmc_helper import (
|
||||
Encryption,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
ReturnCodes,
|
||||
UnableToDecodeError,
|
||||
)
|
||||
except ImportError:
|
||||
from ilorest.rdmc_helper import (
|
||||
Encryption,
|
||||
InvalidCommandLineErrorOPTS,
|
||||
ReturnCodes,
|
||||
UnableToDecodeError,
|
||||
)
|
||||
|
||||
|
||||
class SetPasswordCommand:
|
||||
"""Set password class command"""
|
||||
|
||||
def __init__(self):
|
||||
self.ident = {
|
||||
"name": "setpassword",
|
||||
"usage": None,
|
||||
"description": "Sets the admin password and power-on password\n"
|
||||
"setpassword --newpassword <NEW_PASSWORD> --currentpassword <OLD_PASSWORD> [OPTIONS]\n\n\t"
|
||||
"Setting the admin password with no previous password set."
|
||||
"\n\texample: setpassword --newpassword testnew --currentpassword None\n\n\tSetting the admin "
|
||||
"password back to nothing.\n\texample: setpassword --newpassword None --currentpassword testnew "
|
||||
"\n\n\tSetting the power on password.\n\texample: setpassword"
|
||||
" --newpassword testnew --currentpassword None --poweron\n\tNote: "
|
||||
"if it is empty password, send None as above.",
|
||||
"summary": "Sets the admin password and power-on password",
|
||||
"aliases": [],
|
||||
"auxcommands": [
|
||||
"LoginCommand",
|
||||
"SetCommand",
|
||||
"SelectCommand",
|
||||
"CommitCommand",
|
||||
"RebootCommand",
|
||||
"LogoutCommand",
|
||||
],
|
||||
}
|
||||
self.cmdbase = None
|
||||
self.rdmc = None
|
||||
self.auxcommands = dict()
|
||||
|
||||
def run(self, line, help_disp=False):
|
||||
"""Main set password worker function
|
||||
|
||||
:param line: string of arguments passed in
|
||||
:type line: str.
|
||||
"""
|
||||
if help_disp:
|
||||
self.parser.print_help()
|
||||
return ReturnCodes.SUCCESS
|
||||
try:
|
||||
(options, args) = self.rdmc.rdmc_parse_arglist(self, line)
|
||||
except (InvalidCommandLineErrorOPTS, SystemExit):
|
||||
if ("-h" in line) or ("--help" in line):
|
||||
return ReturnCodes.SUCCESS
|
||||
else:
|
||||
raise InvalidCommandLineErrorOPTS("")
|
||||
|
||||
self.setpasswordvalidation(options)
|
||||
|
||||
# if not args:
|
||||
# self.rdmc.ui.printer('Please input the current password.\n')
|
||||
# tempoldpass = getpass.getpass()
|
||||
|
||||
# if tempoldpass and tempoldpass != '\r':
|
||||
# tempoldpass = tempoldpass
|
||||
# else:
|
||||
# tempoldpass = '""'
|
||||
|
||||
# self.rdmc.ui.printer('Please input the new password.\n')
|
||||
# tempnewpass = getpass.getpass()
|
||||
|
||||
# if tempnewpass and tempnewpass != '\r':
|
||||
# tempnewpass = tempnewpass
|
||||
# else:
|
||||
# tempnewpass = '""'
|
||||
# args.extend([tempnewpass, tempoldpass])
|
||||
|
||||
# if len(args) < 2:
|
||||
# raise InvalidCommandLineError("Please pass both new password and old password.")
|
||||
|
||||
args = list()
|
||||
args.append(options.newpassword)
|
||||
args.append(options.currentpassword)
|
||||
count = 0
|
||||
for arg in args:
|
||||
if arg:
|
||||
if arg.lower() == "none" or arg.lower() == "null" or arg is None:
|
||||
args[count] = ""
|
||||
elif len(arg) > 2:
|
||||
if ('"' in arg[0] and '"' in arg[-1]) or ("'" in arg[0] and "'" in arg[-1]):
|
||||
args[count] = arg[1:-1]
|
||||
elif len(arg) == 2:
|
||||
if (arg[0] == '"' and arg[1] == '"') or (arg[0] == "'" and arg[1] == "'"):
|
||||
args[count] = ""
|
||||
count += 1
|
||||
|
||||
if options.encode:
|
||||
_args = []
|
||||
for arg in args:
|
||||
try:
|
||||
arg = Encryption.decode_credentials(arg)
|
||||
if isinstance(arg, bytes):
|
||||
arg = arg.decode("utf-8")
|
||||
_args.append(arg)
|
||||
except UnableToDecodeError:
|
||||
_args.append(arg)
|
||||
args = _args
|
||||
if self.rdmc.app.typepath.defs.isgen10:
|
||||
bodydict = self.rdmc.app.get_handler(self.rdmc.app.typepath.defs.biospath, service=True, silent=True).dict
|
||||
|
||||
for item in bodydict["Actions"]:
|
||||
if "ChangePassword" in item:
|
||||
path = bodydict["Actions"][item]["target"]
|
||||
break
|
||||
|
||||
if options.poweron:
|
||||
body = {
|
||||
"PasswordName": "User",
|
||||
"OldPassword": args[1],
|
||||
"NewPassword": args[0],
|
||||
}
|
||||
else:
|
||||
body = {
|
||||
"PasswordName": "Administrator",
|
||||
"OldPassword": args[1],
|
||||
"NewPassword": args[0],
|
||||
}
|
||||
|
||||
self.rdmc.app.post_handler(path, body)
|
||||
else:
|
||||
if options.poweron:
|
||||
self.auxcommands["select"].run("HpBios.")
|
||||
self.auxcommands["set"].run("PowerOnPassword=%s OldPowerOnPassword=%s" % (args[0], args[1]))
|
||||
self.auxcommands["commit"].run("")
|
||||
else:
|
||||
self.auxcommands["select"].run("HpBios.")
|
||||
self.auxcommands["set"].run("AdminPassword=%s OldAdminPassword=%s" % (args[0], args[1]))
|
||||
self.auxcommands["commit"].run("")
|
||||
self.rdmc.ui.printer(
|
||||
"\nThe session will now be terminated.\n"
|
||||
" login again with updated credentials in order to continue.\n"
|
||||
)
|
||||
self.auxcommands["logout"].run("")
|
||||
|
||||
if options:
|
||||
if options.reboot:
|
||||
self.auxcommands["reboot"].run(options.reboot)
|
||||
|
||||
self.cmdbase.logout_routine(self, options)
|
||||
return ReturnCodes.SUCCESS
|
||||
|
||||
def setpasswordvalidation(self, options):
|
||||
"""Results method validation function
|
||||
|
||||
:param options: command line options
|
||||
:type options: list.
|
||||
"""
|
||||
self.cmdbase.login_select_validation(self, options)
|
||||
|
||||
def definearguments(self, customparser):
|
||||
"""Wrapper function for new command main function
|
||||
|
||||
:param customparser: command line input
|
||||
:type customparser: parser.
|
||||
"""
|
||||
if not customparser:
|
||||
return
|
||||
|
||||
self.cmdbase.add_login_arguments_group(customparser)
|
||||
|
||||
customparser.add_argument(
|
||||
"--currentpassword",
|
||||
dest="currentpassword",
|
||||
help="Use this flag to provide current password.",
|
||||
required=True,
|
||||
)
|
||||
|
||||
customparser.add_argument(
|
||||
"--newpassword",
|
||||
dest="newpassword",
|
||||
help="Use this flag to provide new password.",
|
||||
required=True,
|
||||
)
|
||||
|
||||
customparser.add_argument(
|
||||
"--reboot",
|
||||
dest="reboot",
|
||||
help="Use this flag to perform a reboot command function after "
|
||||
"completion of operations. 'REBOOT' is a replaceable parameter "
|
||||
"that can have multiple values. For help with parameters and "
|
||||
"descriptions regarding the reboot flag, run help reboot.",
|
||||
default=None,
|
||||
)
|
||||
customparser.add_argument(
|
||||
"--poweron",
|
||||
dest="poweron",
|
||||
action="store_true",
|
||||
help="""Use this flag to set power on password instead""",
|
||||
default=None,
|
||||
)
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in new issue
Block a user