Files
offline_kubespray/collection/dellemc/openmanage/plugins/modules/idrac_bios.py
ByeonJungHun 360c6eef4a offline 작업
2024-02-19 16:02:29 +09:00

427 lines
17 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Dell EMC OpenManage Ansible Modules
# Version 3.5.0
# Copyright (C) 2018-2021 Dell Inc. or its subsidiaries. All Rights Reserved.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
---
module: idrac_bios
short_description: Configure the BIOS attributes
version_added: "2.1.0"
description:
- This module allows to configure the BIOS attributes.
extends_documentation_fragment:
- dellemc.openmanage.idrac_auth_options
options:
share_name:
type: str
description: Network share or a local path.
share_user:
type: str
description: Network share user name. Use the format 'user@domain' or 'domain\\user' if user is part of a domain.
This option is mandatory for CIFS share.
share_password:
type: str
description: Network share user password. This option is mandatory for CIFS share.
aliases: ['share_pwd']
share_mnt:
type: str
description: Local mount path of the network share with read-write permission for ansible user.
This option is mandatory for network shares.
boot_mode:
type: str
description:
- (deprecated)Sets boot mode to BIOS or UEFI.
- This option is deprecated, and will be removed in later version. Use I(attributes)
for configuring the BIOS attributes.
- I(boot_mode) is mutually exclusive with I(boot_sources).
choices: [Bios, Uefi]
nvme_mode:
type: str
description:
- (deprecated)Configures the NVME mode in the iDRAC 9 based PowerEdge Servers.
- This option is deprecated, and will be removed in later version. Use I(attributes)
for configuring the BIOS attributes.
- I(nvme_mode) is mutually exclusive with I(boot_sources).
choices: [NonRaid, Raid]
secure_boot_mode:
type: str
description:
- (deprecated)Configures how the BIOS uses the Secure Boot Policy Objects in iDRAC 9 based PowerEdge Servers.
- This option is deprecated, and will be removed in later version. Use I(attributes)
for configuring the BIOS attributes.
- I(secure_boot_mode) is mutually exclusive with I(boot_sources).
choices: [AuditMode, DeployedMode, SetupMode, UserMode]
onetime_boot_mode:
type: str
description:
- (deprecated)Configures the one time boot mode setting.
- This option is deprecated, and will be removed in later version. Use I(attributes)
for configuring the BIOS attributes.
- I(onetime_boot_mode) is mutually exclusive with I(boot_sources).
choices: [Disabled, OneTimeBootSeq, OneTimeCustomBootSeqStr, OneTimeCustomHddSeqStr,
OneTimeCustomUefiBootSeqStr, OneTimeHddSeq, OneTimeUefiBootSeq]
boot_sequence:
type: str
description:
- "(deprecated)Allows to set the boot sequence in BIOS boot mode or Secure UEFI boot mode by rearranging the
boot entries in Fully Qualified Device Descriptor (FQDD)."
- TThis option is deprecated, and will be removed in later version. Use I(attributes)
for configuring the BIOS attributes.
- I(boot_sequence) is mutually exclusive with I(boot_sources).
attributes:
type: dict
description:
- Dictionary of BIOS attributes and value pair. Attributes should be
part of the Redfish Dell BIOS Attribute Registry. Use
U(https://I(idrac_ip)/redfish/v1/Systems/System.Embedded.1/Bios) to view the Redfish URI.
- If deprecated options are provided and the same is repeated in I(attributes) then values in I(attributes) will
take precedence.
- I(attributes) is mutually exclusive with I(boot_sources).
boot_sources:
type: list
elements: raw
description:
- List of boot devices to set the boot sources settings.
- I(boot_sources) is mutually exclusive with I(attributes), I(boot_sequence),
I(onetime_boot_mode), I(secure_boot_mode), I(nvme_mode), I(boot_mode).
requirements:
- "omsdk"
- "python >= 2.7.5"
author:
- "Felix Stephen (@felixs88)"
- "Anooja Vardhineni (@anooja-vardhineni)"
notes:
- This module requires 'Administrator' privilege for I(idrac_user).
- Run this module from a system that has direct access to DellEMC iDRAC.
- This module supports C(check_mode).
"""
EXAMPLES = """
---
- name: Configure generic attributes of the BIOS
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
attributes:
BootMode : "Bios"
OneTimeBootMode: "Enabled"
BootSeqRetry: "Enabled"
- name: Configure PXE generic attributes
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
attributes:
PxeDev1EnDis: "Enabled"
PxeDev1Protocol: "IPV4"
PxeDev1VlanEnDis: "Enabled"
PxeDev1VlanId: 1
PxeDev1Interface: "NIC.Embedded.1-1-1"
PxeDev1VlanPriority: 2
- name: Configure boot sources
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
boot_sources:
- Name : "NIC.Integrated.1-2-3"
Enabled : true
Index : 0
- name: Configure multiple boot sources
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
boot_sources:
- Name : "NIC.Integrated.1-1-1"
Enabled : true
Index : 0
- Name : "NIC.Integrated.2-2-2"
Enabled : true
Index : 1
- Name : "NIC.Integrated.3-3-3"
Enabled : true
Index : 2
- name: Configure boot sources - Enabling
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
boot_sources:
- Name : "NIC.Integrated.1-1-1"
Enabled : true
- name: Configure boot sources - Index
dellemc.openmanage.idrac_bios:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
boot_sources:
- Name : "NIC.Integrated.1-1-1"
Index : 0
"""
RETURN = r'''
---
msg:
description: Configures the BIOS configuration attributes.
returned: success
type: dict
sample: {
"@odata.context": "/redfish/v1/$metadata#DellJob.DellJob",
"@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_873888162305",
"@odata.type": "#DellJob.v1_0_0.DellJob",
"CompletionTime": "2020-04-20T18:50:20",
"Description": "Job Instance",
"EndTime": null,
"Id": "JID_873888162305",
"JobState": "Completed",
"JobType": "ImportConfiguration",
"Message": "Successfully imported and applied Server Configuration Profile.",
"MessageArgs": [],
"MessageId": "SYS053",
"Name": "Import Configuration",
"PercentComplete": 100,
"StartTime": "TIME_NOW",
"Status": "Success",
"TargetSettingsURI": null,
"retval": true
}
error_info:
description: Details of the HTTP Error.
returned: on HTTP error
type: dict
sample: {
"error": {
"code": "Base.1.0.GeneralError",
"message": "A general error has occurred. See ExtendedInfo for more information.",
"@Message.ExtendedInfo": [
{
"MessageId": "GEN1234",
"RelatedProperties": [],
"Message": "Unable to process the request because an error occurred.",
"MessageArgs": [],
"Severity": "Critical",
"Resolution": "Retry the operation. If the issue persists, contact your system administrator."
}
]
}
}
'''
import os
import tempfile
import json
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
from ansible.module_utils.urls import ConnectionError, SSLValidationError
from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection
from ansible.module_utils.basic import AnsibleModule
try:
from omdrivers.enums.iDRAC.BIOS import (BootModeTypes, NvmeModeTypes, SecureBootModeTypes,
OneTimeBootModeTypes)
from omdrivers.enums.iDRAC.iDRACEnums import BootModeEnum
from omsdk.sdkfile import file_share_manager
from omsdk.sdkcreds import UserCredentials
except ImportError:
pass
def run_server_bios_config(idrac, module):
msg = {}
temp_dir = tempfile.gettempdir() + os.sep
share_name = module.params.get('share_name')
share_path = share_name if share_name is not None else temp_dir
idrac.use_redfish = True
upd_share = file_share_manager.create_share_obj(share_path=share_path,
mount_point=module.params['share_mnt'],
isFolder=True,
creds=UserCredentials(
module.params['share_user'],
module.params['share_password'])
)
if not upd_share.IsValid:
module.fail_json(msg="Unable to access the share. Ensure that the share name, "
"share mount, and share credentials provided are correct.")
if module.params['boot_sources']:
_validate_params(module.params['boot_sources'])
if module.check_mode:
idrac.config_mgr.is_change_applicable()
msg = idrac.config_mgr.configure_boot_sources(
input_boot_devices=module.params['boot_sources'])
return msg
idrac.config_mgr.set_liason_share(upd_share)
if module.params['boot_mode'] and not (module.params['attributes'] and 'BootMode' in module.params['attributes']):
idrac.config_mgr.configure_boot_mode(boot_mode=BootModeTypes[module.params['boot_mode']])
if module.params['nvme_mode'] and not (module.params['attributes'] and 'NvmeMode' in module.params['attributes']):
idrac.config_mgr.configure_nvme_mode(nvme_mode=NvmeModeTypes[module.params['nvme_mode']])
if module.params['secure_boot_mode'] and not (module.params['attributes'] and 'SecureBootMode' in
module.params['attributes']):
idrac.config_mgr.configure_secure_boot_mode(
secure_boot_mode=SecureBootModeTypes[module.params['secure_boot_mode']])
if module.params['onetime_boot_mode'] and not (module.params['attributes'] and 'OneTimeBootMode' in
module.params['attributes']):
idrac.config_mgr.configure_onetime_boot_mode(
onetime_boot_mode=OneTimeBootModeTypes[module.params['onetime_boot_mode']])
if module.params["boot_mode"] is not None and module.params["boot_sequence"] is not None:
idrac.config_mgr.configure_boot_sequence(
boot_mode=BootModeEnum[module.params['boot_mode']],
boot_sequence=module.params['boot_sequence']
)
if module.params['attributes']:
msg['msg'] = idrac.config_mgr.configure_bios(
bios_attr_val=module.params['attributes'])
if module.check_mode:
msg = idrac.config_mgr.is_change_applicable()
else:
msg = idrac.config_mgr.apply_changes(reboot=True)
return msg
def _validate_params(params):
"""
Validate list of dict params.
:param params: Ansible list of dict
:return: bool or error.
"""
fields = [
{"name": "Name", "type": str, "required": True},
{"name": "Index", "type": int, "required": False, "min": 0},
{"name": "Enabled", "type": bool, "required": False}
]
default = ['Name', 'Index', 'Enabled']
for attr in params:
if not isinstance(attr, dict):
msg = "{0} must be of type: {1}. {2} ({3}) provided.".format(
"attribute values", dict, attr, type(attr))
return msg
elif all(k in default for k in attr.keys()):
msg = check_params(attr, fields)
return msg
else:
msg = "attribute keys must be one of the {0}.".format(default)
return msg
msg = _validate_name_index_duplication(params)
return msg
def _validate_name_index_duplication(params):
"""
Validate for duplicate names and indices.
:param params: Ansible list of dict
:return: bool or error.
"""
msg = ""
for i in range(len(params) - 1):
for j in range(i + 1, len(params)):
if params[i]['Name'] == params[j]['Name']:
msg = "duplicate name {0}".format(params[i]['Name'])
return msg
return msg
def check_params(each, fields):
"""
Each dictionary parameters validation as per the rule defined in fields.
:param each: validating each dictionary
:param fields: list of dictionary which has the set of rules.
:return: tuple which has err and message
"""
msg = ""
for f in fields:
if f['name'] not in each and f["required"] is False:
continue
if not f["name"] in each and f["required"] is True:
msg = "{0} is required and must be of type: {1}".format(f['name'], f['type'])
elif not isinstance(each[f["name"]], f["type"]):
msg = "{0} must be of type: {1}. {2} ({3}) provided.".format(
f['name'], f['type'], each[f['name']], type(each[f['name']]))
elif f['name'] in each and isinstance(each[f['name']], int) and 'min' in f:
if each[f['name']] < f['min']:
msg = "{0} must be greater than or equal to: {1}".format(f['name'], f['min'])
return msg
def main():
mutual_exclusive_args = [['boot_sources', 'attributes'], ['boot_sources', 'secure_boot_mode'],
['boot_sources', 'boot_mode'], ['boot_sources', 'boot_sequence'],
['boot_sources', 'nvme_mode'], ['boot_sources', 'onetime_boot_mode']]
module = AnsibleModule(
argument_spec={
"idrac_ip": {"required": True, "type": 'str'},
"idrac_user": {"required": True, "type": 'str'},
"idrac_password": {"required": True, "type": 'str', "aliases": ['idrac_pwd'], "no_log": True},
"idrac_port": {"required": False, "default": 443, "type": 'int'},
"share_name": {"required": False, "type": 'str'},
"share_user": {"required": False, "type": 'str'},
"share_password": {"required": False, "type": 'str', "aliases": ['share_pwd'], "no_log": True},
"share_mnt": {"required": False, "type": 'str'},
"boot_mode": {"required": False, "choices": ['Bios', 'Uefi']},
"nvme_mode": {"required": False, "choices": ['NonRaid', 'Raid']},
"secure_boot_mode": {"required": False, "choices": ['AuditMode', 'DeployedMode', 'SetupMode', 'UserMode']},
"onetime_boot_mode": {"required": False, "choices": ['Disabled', 'OneTimeBootSeq',
'OneTimeCustomBootSeqStr', 'OneTimeCustomHddSeqStr',
'OneTimeCustomUefiBootSeqStr', 'OneTimeHddSeq',
'OneTimeUefiBootSeq']},
"boot_sequence": {"required": False, "type": "str"},
"attributes": {"required": False, "type": 'dict'},
"boot_sources": {"required": False, "type": 'list', 'elements': 'raw'}
},
mutually_exclusive=mutual_exclusive_args,
supports_check_mode=True
)
try:
with iDRACConnection(module.params) as idrac:
msg = run_server_bios_config(idrac, module)
changed, failed = False, False
if msg.get('Status') == "Success":
changed = True
if msg.get('Message') == "No changes found to commit!":
changed = False
elif msg.get('Status') == "Failed":
failed = True
except HTTPError as err:
module.fail_json(msg=str(err), error_info=json.load(err))
except URLError as err:
module.exit_json(msg=str(err), unreachable=True)
except AttributeError as err:
if "NoneType" in str(err):
module.fail_json(msg="Unable to access the share. Ensure that the share name, "
"share mount, and share credentials provided are correct.")
except (RuntimeError, SSLValidationError, ConnectionError, KeyError,
ImportError, ValueError, TypeError) as e:
module.fail_json(msg=str(e))
module.exit_json(msg=msg, changed=changed, failed=failed)
if __name__ == '__main__':
main()