summaryrefslogtreecommitdiffstats
path: root/ansible_collections/dellemc/openmanage/roles/redfish_firmware
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:35 +0000
commit7fec0b69a082aaeec72fee0612766aa42f6b1b4d (patch)
treeefb569b86ca4da888717f5433e757145fa322e08 /ansible_collections/dellemc/openmanage/roles/redfish_firmware
parentReleasing progress-linux version 7.7.0+dfsg-3~progress7.99u1. (diff)
downloadansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.tar.xz
ansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.zip
Merging upstream version 9.4.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/dellemc/openmanage/roles/redfish_firmware')
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/README.md219
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/defaults/main.yml9
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/handlers/main.yml2
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/argument_specs.yml60
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/main.yml55
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/converge.yml74
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/molecule.yml15
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/converge.yml174
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/molecule.yml15
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/cleanup.yml16
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/prepare.yml17
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/tasks/main.yml16
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/inventory2
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/test.yml5
-rw-r--r--ansible_collections/dellemc/openmanage/roles/redfish_firmware/vars/main.yml2
15 files changed, 681 insertions, 0 deletions
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/README.md b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/README.md
new file mode 100644
index 000000000..69f9989cf
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/README.md
@@ -0,0 +1,219 @@
+# redfish_firmware
+
+To perform a component firmware update using the image file available on the local or remote system.
+
+## Requirements
+
+---
+
+
+### Development
+Requirements to develop and contribute to the role.
+
+```
+ansible
+docker
+molecule
+python
+```
+
+### Production
+
+Requirements to use the role.
+
+```
+ansible
+python
+```
+
+## Ansible collections
+
+Collections required to use the role.
+
+```
+dellemc.openmanage
+```
+
+## Role Variables
+
+---
+
+<table>
+<thead>
+ <tr>
+ <th>Name</th>
+ <th>Required</th>
+ <th>Default Value</th>
+ <th>Choices</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+</thead>
+<tbody>
+ <tr>
+ <td>hostname</td>
+ <td>true</td>
+ <td></td>
+ <td></td>
+ <td>str</td>
+ <td>- iDRAC IP Address</td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>true</td>
+ <td></td>
+ <td></td>
+ <td>str</td>
+ <td>- iDRAC username</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>true</td>
+ <td></td>
+ <td></td>
+ <td>str</td>
+ <td>- iDRAC user password.</td>
+ </tr>
+ <tr>
+ <td>https_port</td>
+ <td>false</td>
+ <td>443</td>
+ <td></td>
+ <td>int</td>
+ <td>- iDRAC port.</td>
+ </tr>
+ <tr>
+ <td>validate_certs</td>
+ <td>false</td>
+ <td>true</td>
+ <td></td>
+ <td>bool</td>
+ <td>- If C(false), the SSL certificates will not be validated.<br>- Configure C(false) only on personally controlled sites where self-signed certificates are used.</td>
+ </tr>
+ <tr>
+ <td>ca_path</td>
+ <td>false</td>
+ <td></td>
+ <td></td>
+ <td>path</td>
+ <td>- The Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.</td>
+ </tr>
+ <tr>
+ <td>https_timeout</td>
+ <td>false</td>
+ <td>30</td>
+ <td></td>
+ <td>int</td>
+ <td>- The socket level timeout in seconds.</td>
+ </tr>
+ <tr>
+ <td>image_uri</td>
+ <td>false</td>
+ <td></td>
+ <td></td>
+ <td>str</td>
+ <td>- Firmware Image location URI or local path.
+ <br>- For example- U(http://<web_address>/components.exe) or /home/firmware_repo/component.exe.
+ </td>
+ </tr>
+ <tr>
+ <td>transfer_protocol</td>
+ <td>false</td>
+ <td>HTTP</td>
+ <td>"CIFS", "FTP", "HTTP", "HTTPS", "NSF", "OEM", "SCP", "SFTP", "TFTP"</td>
+ <td>str</td>
+ <td>- Protocol used to transfer the firmware image file. Applicable for URI based update.</td>
+ </tr>
+ <tr>
+ <td>job_wait</td>
+ <td>false</td>
+ <td>true</td>
+ <td></td>
+ <td>str</td>
+ <td>- Provides the option to wait for job completion.</td>
+ </tr>
+ <tr>
+ <td>job_wait_timeout</td>
+ <td>false</td>
+ <td>3600</td>
+ <td></td>
+ <td>str</td>
+ <td>- The maximum wait time of I(job_wait) in seconds. The job is tracked only for this duration.
+ <br>- This option is applicable when I(job_wait) is C(True).
+ </td>
+ </tr>
+</tbody>
+</table>
+
+## Fact variables
+
+<table>
+<thead>
+ <tr>
+ <th>Name</th>
+ <th>Sample</th>
+ <th>Description</th>
+ </tr>
+</thead>
+ <tbody>
+ <tr>
+ <td>redfish_firmware_out</td>
+ <td>{
+ msg: Successfully submitted the firmware update task.
+ task: {
+ "id": "JID_XXXXXXXXXXXX",
+ "uri": "/redfish/v1/TaskService/Tasks/JID_XXXXXXXXXXXX"
+ }
+ }</td>
+ <td>Returns the output of the firmware update status.</td>
+ </tr>
+ </tbody>
+</table>
+
+## Examples
+
+---
+
+```
+- name: Update the firmware from a single executable file available in HTTP protocol
+ ansible.builtin.include_role:
+ name: redfish_firmware:
+ vars:
+ hostname: "192.168.0.1"
+ username: "username"
+ password: "password"
+ image_uri: "http://192.168.0.2/firmware_repo/component.exe"
+ transfer_protocol: "HTTP"
+```
+
+```
+- name: Update the firmware from a single executable file available in a local path
+ ansible.builtin.include_role:
+ name: redfish_firmware:
+ vars:
+ hostname: "192.168.0.1"
+ username: "username"
+ password: "password"
+ image_uri: "/home/firmware_repo/component.exe"
+```
+
+```
+- name: Update the firmware from a single executable file available in a HTTP protocol with job_wait_timeout
+ ansible.builtin.include_role:
+ name: redfish_firmware:
+ vars:
+ hostname: "192.168.0.1"
+ username: "user_name"
+ password: "user_password"
+ ca_path: "/path/to/ca_cert.pem"
+ image_uri: "http://192.168.0.2/firmware_repo/component.exe"
+ transfer_protocol: "HTTP"
+ job_wait_timeout: 600
+```
+
+## Author Information
+
+---
+
+Dell Technologies <br>
+Shivam Sharma (Shivam.Sharma3@Dell.com) 2023
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/defaults/main.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/defaults/main.yml
new file mode 100644
index 000000000..6a1d8fe6e
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# defaults file for redfish_firmware
+
+https_port: 443
+validate_certs: true
+https_timeout: 30
+job_wait_timeout: 3600
+transfer_protocol: HTTP
+job_wait: true
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/handlers/main.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/handlers/main.yml
new file mode 100644
index 000000000..6c0214362
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/handlers/main.yml
@@ -0,0 +1,2 @@
+---
+# handlers file for redfish_firmware
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/argument_specs.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/argument_specs.yml
new file mode 100644
index 000000000..1396b9bd8
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/argument_specs.yml
@@ -0,0 +1,60 @@
+---
+argument_specs:
+ main:
+ version_added: "7.5.0"
+ short_description: Update a component firmware using the image file available on the local or remote system
+ description:
+ - This module allows the firmware update of only one component at a time. If the module is run for more than one component, an error message is returned.
+ - Depending on the component, the firmware update is applied after an automatic or manual reboot.
+ options:
+ hostname:
+ required: true
+ type: str
+ description: iDRAC IP Address or hostname.
+ username:
+ type: str
+ description: iDRAC username with admin privileges.
+ password:
+ type: str
+ description: iDRAC user password.
+ https_port:
+ type: int
+ description: iDRAC port.
+ default: 443
+ validate_certs:
+ description:
+ - If C(False), the SSL certificates will not be validated.
+ - Configure C(False) only on personally controlled sites where self-signed certificates are used.
+ - Prior to collection version 5.0.0, I(validate_certs) is C(False) by default.
+ type: bool
+ default: true
+ ca_path:
+ description:
+ - The Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
+ type: path
+ http_timeout:
+ description: The socket level timeout in seconds.
+ type: int
+ default: 30
+ image_uri:
+ description:
+ - Firmware Image location URI or local path.
+ - For example- U(http://<web_address>/components.exe) or /home/firmware_repo/component.exe.
+ type: str
+ required: true
+ transfer_protocol:
+ description: Protocol used to transfer the firmware image file. Applicable for URI based update.
+ type: str
+ default: HTTP
+ choices:
+ ["CIFS", "FTP", "HTTP", "HTTPS", "NSF", "OEM", "SCP", "SFTP", "TFTP"]
+ job_wait:
+ description: Provides the option to wait for job completion.
+ type: bool
+ default: true
+ job_wait_timeout:
+ description:
+ - The maximum wait time of I(job_wait) in seconds. The job is tracked only for this duration.
+ - This option is applicable when I(job_wait) is C(True).
+ type: int
+ default: 3600
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/main.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/main.yml
new file mode 100644
index 000000000..f9b757aff
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/meta/main.yml
@@ -0,0 +1,55 @@
+galaxy_info:
+ author: "Shivam Sharma"
+ description: To perform a component firmware update using the image file available on the local or remote system.
+ company: Dell Technologies
+
+ # If the issue tracker for your role is not on github, uncomment the
+ # next line and provide a value
+ # issue_tracker_url: http://example.com/issue/tracker
+
+ # Choose a valid license ID from https://spdx.org - some suggested licenses:
+ # - BSD-3-Clause (default)
+ # - MIT
+ # - GPL-2.0-or-later
+ # - GPL-3.0-only
+ # - Apache-2.0
+ # - CC-BY-4.0
+ license: GPL-3.0-only
+
+ min_ansible_version: "2.13"
+
+ # If this a Container Enabled role, provide the minimum Ansible Container version.
+ # min_ansible_container_version:
+
+ #
+ # Provide a list of supported platforms, and for each platform a list of versions.
+ # If you don't wish to enumerate all versions for a particular platform, use 'all'.
+ # To view available platforms and versions (or releases), visit:
+ # https://galaxy.ansible.com/api/v1/platforms/
+ #
+ platforms:
+ - name: Ubuntu
+ versions:
+ - jammy
+ - name: SLES
+ versions:
+ - "15SP3"
+ - "15SP4"
+ - name: EL
+ versions:
+ - "9"
+ - "8"
+
+ galaxy_tags:
+ []
+ # List tags for your role here, one per line. A tag is a keyword that describes
+ # and categorizes the role. Users find roles by searching for tags. Be sure to
+ # remove the '[]' above, if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
+ # Maximum 20 tags per role.
+
+dependencies:
+ []
+ # List your role dependencies here, one per line. Be sure to remove the '[]' above,
+ # if you add dependencies to this list.
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/converge.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/converge.yml
new file mode 100644
index 000000000..26d2c476c
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/converge.yml
@@ -0,0 +1,74 @@
+---
+- name: Converge
+ hosts: all
+ vars:
+ redfish_firmware_image_url_without_reboot: "{{ lookup('env', 'redfish_firmware_image_url_without_reboot') }}"
+ redfish_firmware_image_url_need_reboot: "{{ lookup('env', 'redfish_firmware_image_url_need_reboot') }}"
+ redfish_firmware_image_local_path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ gather_facts: false
+ tasks:
+ - name: Checking if HTTP url is empty
+ ansible.builtin.fail:
+ msg: Please provide HTTP url for redfish_firmware in molecule.yml
+ when: redfish_firmware_image_url_without_reboot == "" and redfish_firmware_image_url_need_reboot == ""
+
+ - name: Downloading firmware image for local manual reboot
+ ansible.builtin.get_url:
+ url: "{{ redfish_firmware_image_url_need_reboot }}"
+ dest: "{{ redfish_firmware_image_local_path }}"
+ mode: "0755"
+ delegate_to: localhost
+
+ - name: Initializing idrac common inputs to use as aliases
+ ansible.builtin.set_fact:
+ common_input: &idrac_input
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ no_log: true
+
+ - name: TC - 001 - Provide valid HTTP image_uri with default transfer_protocol with auto reboot
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ <<: *idrac_input
+ image_uri: "{{ redfish_firmware_image_url_without_reboot }}"
+ job_wait_timeout: 3600
+
+ - name: TC - 001 - Asserting after performing update with valid image_uri and default transfter_protocol with auto reboot
+ ansible.builtin.assert:
+ that:
+ - redfish_firmware_out.msg == 'Successfully updated the firmware.'
+ - redfish_firmware_out.changed
+
+ - name: TC - 002 - Provide valid local image_uri firmware to schedule job with job_wait_timeout 60 secs
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ <<: *idrac_input
+ image_uri: "{{ redfish_firmware_image_url_need_reboot }}"
+ job_wait_timeout: 60
+
+ - name: TC - 002 - Asserting after performing update with local image_uri firmware to schedule job
+ ansible.builtin.assert:
+ that:
+ - redfish_firmware_out.msg == "Successfully scheduled the firmware job."
+ - redfish_firmware_out.changed
+
+ - name: TC - 002 - Deleting the schedule job in iDRAC
+ ansible.builtin.uri:
+ url: "https://{{ lookup('env', 'IDRAC_IP') }}/redfish/v1/JobService/Jobs/{{ redfish_firmware_out.task.id }}"
+ validate_certs: false
+ method: "DELETE"
+ user: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ headers:
+ Accept: "application/json"
+ Content-Type: "application/json"
+ OData-Version: "4.0"
+ body_format: "json"
+ status_code:
+ - 200
+ return_content: true
+ no_log: true
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/molecule.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/molecule.yml
new file mode 100644
index 000000000..484f43c65
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/default/molecule.yml
@@ -0,0 +1,15 @@
+---
+provisioner:
+ name: ansible
+ playbooks:
+ prepare: ../resources/prepare.yml
+ cleanup: ../resources/cleanup.yml
+scenario:
+ test_sequence:
+ - dependency
+ - cleanup
+ - destroy
+ - syntax
+ - create
+ - converge
+ - destroy
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/converge.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/converge.yml
new file mode 100644
index 000000000..86196dc82
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/converge.yml
@@ -0,0 +1,174 @@
+---
+- name: Converge
+ hosts: all
+ gather_facts: false
+ vars:
+ redfish_firmware_image_url_without_reboot: "{{ lookup('env', 'redfish_firmware_image_url_without_reboot') }}"
+ redfish_firmware_image_url_need_reboot: "{{ lookup('env', 'redfish_firmware_image_url_need_reboot') }}"
+ redfish_firmware_image_local_path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ tasks:
+ - name: Checking if HTTP url is empty
+ ansible.builtin.fail:
+ msg: Please provide HTTP url for redfish_firmware in molecule.yml
+ when: redfish_firmware_image_url_without_reboot == "" and redfish_firmware_image_url_need_reboot == ""
+
+ - name: Downloading firmware image for local manual reboot
+ ansible.builtin.get_url:
+ url: "{{ redfish_firmware_image_url_need_reboot }}"
+ dest: "{{ redfish_firmware_image_local_path }}"
+ mode: "0755"
+ delegate_to: localhost
+
+ - name: TC - 003 - Provide wrong hostname
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "randomHostname"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ image_uri: "{{ redfish_firmware_image_url_need_reboot }}"
+ job_wait_timeout: 60
+ ignore_errors: true
+ ignore_unreachable: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 003 - Asserting wrong hostname
+ ansible.builtin.assert:
+ that:
+ - redfish_firmware_out.msg == "<urlopen error [Errno -2] Name or service not known>" or
+ redfish_firmware_out.msg == "<urlopen error Unable to resolve hostname or IP randomHostname:443.>"
+
+ - name: TC - 004 - Provide wrong username
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "WrongUsername123"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ image_uri: "{{ redfish_firmware_image_url_need_reboot }}"
+ job_wait_timeout: 60
+ ignore_errors: true
+ ignore_unreachable: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 004 - Asserting wrong username
+ ansible.builtin.assert:
+ that:
+ - '"HTTP Error 401" in redfish_firmware_out.msg'
+
+ - name: TC - 005 - Provide wrong password
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "WrongPassword@123"
+ validate_certs: false
+ image_uri: "{{ redfish_firmware_image_url_need_reboot }}"
+ job_wait_timeout: 60
+ ignore_errors: true
+ ignore_unreachable: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 005 - Asserting wrong password
+ ansible.builtin.assert:
+ that: |-
+ ('"HTTP Error 401" in redfish_firmware_out.msg')
+ or
+ ('"urlopen error timed out" in redfish_firmware_out.msg')
+
+ - name: TC - 006 - Providing invalid validate_certs
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: 'someStringValue'
+ image_uri: "{{ redfish_firmware_image_url_need_reboot }}"
+ job_wait_timeout: 60
+ ignore_errors: true
+ ignore_unreachable: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 006 - Asserting invalid validate_certs
+ ansible.builtin.assert:
+ that:
+ - '"Valid booleans include" in redfish_firmware_out.msg'
+
+ - name: TC - 007 - Providing invalid local path in image_uri
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ image_uri: "/tmp/file_not_exists.iso"
+ job_wait_timeout: 60
+ ignore_errors: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 007 - Asserting invalid local path in image_uri
+ ansible.builtin.assert:
+ that:
+ - '"No such file or directory" in redfish_firmware_out.msg'
+
+ - name: TC - 008 - Providing invalid HTTP in image_uri
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ image_uri: "http://www.example.com"
+ job_wait_timeout: 60
+ ignore_errors: true
+ register: redfish_firmware_error_msg
+
+ - name: TC - 008 - Asserting invalid HTTP in image_uri
+ ansible.builtin.assert:
+ that:
+ - redfish_firmware_out.msg == "Firmware update failed."
+ - not redfish_firmware_out.changed
+
+ - name: TC - 009 - Providing job_wait_timeout as -100 with auto reboot firmware component
+ ansible.builtin.import_role:
+ name: redfish_firmware
+ vars:
+ hostname: "{{ lookup('env', 'IDRAC_IP') }}"
+ username: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ validate_certs: false
+ image_uri: "{{ redfish_firmware_image_url_without_reboot }}"
+ job_wait_timeout: -100
+
+ - name: TC - 009 - Asserting job_wait_timeout as -100 with auto reboot firmware component
+ ansible.builtin.assert:
+ that:
+ - redfish_firmware_out.msg == "Successfully submitted the firmware update task."
+ - redfish_firmware_out.changed
+
+ - name: TC - 009 - Waiting for job completion
+ ansible.builtin.uri:
+ url: "https://{{ lookup('env', 'IDRAC_IP') }}/redfish/v1/JobService/Jobs/{{ redfish_firmware_out.task.id }}"
+ validate_certs: false
+ method: "GET"
+ user: "{{ lookup('env', 'IDRAC_USER') }}"
+ password: "{{ lookup('env', 'IDRAC_PASSWORD') }}"
+ headers:
+ Accept: "application/json"
+ Content-Type: "application/json"
+ OData-Version: "4.0"
+ body_format: "json"
+ status_code:
+ - 200
+ return_content: true
+ register: job_result
+ until: job_result.json.JobState == 'Completed' or job_result.json.JobState == 'Failed'
+ retries: 30
+ delay: 10
+ when: redfish_firmware_out.changed # noqa: no-handler
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/molecule.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/molecule.yml
new file mode 100644
index 000000000..484f43c65
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/negative/molecule.yml
@@ -0,0 +1,15 @@
+---
+provisioner:
+ name: ansible
+ playbooks:
+ prepare: ../resources/prepare.yml
+ cleanup: ../resources/cleanup.yml
+scenario:
+ test_sequence:
+ - dependency
+ - cleanup
+ - destroy
+ - syntax
+ - create
+ - converge
+ - destroy
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/cleanup.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/cleanup.yml
new file mode 100644
index 000000000..bfffc48fd
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/cleanup.yml
@@ -0,0 +1,16 @@
+- name: Cleanup
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Check if directory exists
+ ansible.builtin.stat:
+ path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ register: directory_check
+ delegate_to: localhost
+
+ - name: Delete directory if it exists
+ ansible.builtin.file:
+ path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ state: absent
+ when: directory_check.stat.exists
+ delegate_to: localhost
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/prepare.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/prepare.yml
new file mode 100644
index 000000000..17c1a617a
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/molecule/resources/prepare.yml
@@ -0,0 +1,17 @@
+- name: Prepare
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Checking if path exists
+ ansible.builtin.stat:
+ path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ register: directory_check
+ delegate_to: localhost
+
+ - name: Create directory if it doesn't exist
+ ansible.builtin.file:
+ path: "{{ lookup('env', 'redfish_firmware_image_local_path') }}"
+ state: directory
+ mode: "0755"
+ when: directory_check.stat.exists
+ delegate_to: localhost
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tasks/main.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tasks/main.yml
new file mode 100644
index 000000000..418e8a7ac
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+# tasks file for redfish_firmware
+- name: Update the firmware from a single executable file.
+ dellemc.openmanage.redfish_firmware:
+ baseuri: "{{ hostname }}:{{ https_port }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ ca_path: "{{ ca_path | default(omit) }}"
+ timeout: "{{ https_timeout }}"
+ image_uri: "{{ image_uri }}"
+ transfer_protocol: "{{ transfer_protocol }}"
+ job_wait: "{{ job_wait }}"
+ job_wait_timeout: "{{ job_wait_timeout }}"
+ register: redfish_firmware_out
+ delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}"
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/inventory b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/inventory
new file mode 100644
index 000000000..878877b07
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/inventory
@@ -0,0 +1,2 @@
+localhost
+
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/test.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/test.yml
new file mode 100644
index 000000000..8a43f29b7
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/tests/test.yml
@@ -0,0 +1,5 @@
+---
+- name: Upgrading Firmware
+ hosts: all
+ roles:
+ - redfish_firmware
diff --git a/ansible_collections/dellemc/openmanage/roles/redfish_firmware/vars/main.yml b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/vars/main.yml
new file mode 100644
index 000000000..849f79286
--- /dev/null
+++ b/ansible_collections/dellemc/openmanage/roles/redfish_firmware/vars/main.yml
@@ -0,0 +1,2 @@
+---
+# vars file for redfish_firmware