1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/modules/remote_management/dellemc/idrac_firmware.py

208 lines
7 KiB
Python
Raw Normal View History

2020-03-09 10:11:07 +01:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Dell EMC OpenManage Ansible Modules
# Version 2.0
# Copyright (C) 2018-2019 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 = r'''
---
module: idrac_firmware
short_description: Firmware update from a repository on a network share (CIFS, NFS).
description:
- Update the Firmware by connecting to a network share (either CIFS or NFS) that contains a catalog of
available updates.
- Network share should contain a valid repository of Update Packages (DUPs) and a catalog file describing the DUPs.
- All applicable updates contained in the repository are applied to the system.
- This feature is available only with iDRAC Enterprise License.
options:
idrac_ip:
description: iDRAC IP Address.
type: str
required: True
idrac_user:
description: iDRAC username.
type: str
required: True
idrac_password:
description: iDRAC user password.
type: str
required: True
aliases: ['idrac_pwd']
idrac_port:
description: iDRAC port.
type: int
default: 443
share_name:
description: CIFS or NFS Network share.
type: str
required: True
share_user:
description: Network share user in the format 'user@domain' or 'domain\\user' if user is
part of a domain else 'user'. This option is mandatory for CIFS Network Share.
type: str
share_password:
description: Network share user password. This option is mandatory for CIFS Network Share.
type: str
aliases: ['share_pwd']
share_mnt:
description: Local mount path of the network share with read-write permission for ansible user.
This option is mandatory for Network Share.
type: str
required: True
reboot:
description: Whether to reboots after applying the updates or not.
type: bool
default: false
job_wait:
description: Whether to wait for job completion or not.
type: bool
default: true
catalog_file_name:
required: False
description: Catalog file name relative to the I(share_name).
type: str
default: 'Catalog.xml'
requirements:
- "omsdk"
- "python >= 2.7.5"
author: "Rajeev Arakkal (@rajeevarakkal)"
'''
EXAMPLES = """
---
- name: Update firmware from repository on a Network Share
idrac_firmware:
idrac_ip: "192.168.0.1"
idrac_user: "user_name"
idrac_password: "user_password"
share_name: "192.168.0.0:/share"
share_user: "share_user_name"
share_password: "share_user_pwd"
share_mnt: "/mnt/share"
reboot: True
job_wait: True
catalog_file_name: "Catalog.xml"
"""
RETURN = """
---
msg:
type: str
description: Over all firmware update status.
returned: always
sample: "Successfully updated the firmware."
update_status:
type: dict
description: Firmware Update job and progress details from the iDRAC.
returned: success
sample: {
'InstanceID': 'JID_XXXXXXXXXXXX',
'JobState': 'Completed',
'Message': 'Job completed successfully.',
'MessageId': 'REDXXX',
'Name': 'Repository Update',
'JobStartTime': 'NA',
'Status': 'Success',
}
"""
from ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.dellemc_idrac import iDRACConnection
from ansible.module_utils.basic import AnsibleModule
try:
from omsdk.sdkcreds import UserCredentials
from omsdk.sdkfile import FileOnShare
HAS_OMSDK = True
except ImportError:
HAS_OMSDK = False
def _validate_catalog_file(catalog_file_name):
normilized_file_name = catalog_file_name.lower()
if not normilized_file_name:
raise ValueError('catalog_file_name should be a non-empty string.')
elif not normilized_file_name.endswith("xml"):
raise ValueError('catalog_file_name should be an XML file.')
def update_firmware(idrac, module):
"""Update firmware from a network share and return the job details."""
msg = {}
msg['changed'] = False
msg['update_status'] = {}
try:
upd_share = FileOnShare(remote=module.params['share_name'] + "/" + module.params['catalog_file_name'],
mount_point=module.params['share_mnt'],
isFolder=False,
creds=UserCredentials(
module.params['share_user'],
module.params['share_password'])
)
idrac.use_redfish = True
if '12' in idrac.ServerGeneration or '13' in idrac.ServerGeneration:
idrac.use_redfish = False
apply_update = True
msg['update_status'] = idrac.update_mgr.update_from_repo(upd_share,
apply_update,
module.params['reboot'],
module.params['job_wait'])
except RuntimeError as e:
module.fail_json(msg=str(e))
if "Status" in msg['update_status']:
if msg['update_status']['Status'] == "Success":
if module.params['job_wait']:
msg['changed'] = True
else:
module.fail_json(msg='Failed to update firmware.', update_status=msg['update_status'])
return msg
def main():
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": True, "type": 'str'},
"share_user": {"required": False, "type": 'str'},
"share_password": {"required": False, "type": 'str', "aliases": ['share_pwd'], "no_log": True},
"share_mnt": {"required": True, "type": 'str'},
"catalog_file_name": {"required": False, "type": 'str', "default": "Catalog.xml"},
"reboot": {"required": False, "type": 'bool', "default": False},
"job_wait": {"required": False, "type": 'bool', "default": True},
},
supports_check_mode=False)
try:
# Validate the catalog file
_validate_catalog_file(module.params['catalog_file_name'])
# Connect to iDRAC and update firmware
with iDRACConnection(module.params) as idrac:
update_status = update_firmware(idrac, module)
except (ImportError, ValueError, RuntimeError) as e:
module.fail_json(msg=str(e))
module.exit_json(msg='Successfully updated the firmware.', update_status=update_status)
if __name__ == '__main__':
main()