diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 000000000..45cdf6c8d --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,4 @@ +exclude_paths: + - changelogs/ + - .github/ + - roles/idrac_gather_facts/molecule/*/*_assert.yml diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 8ea13f4c0..cfe4eca34 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -102,10 +102,10 @@ jobs: strategy: fail-fast: false matrix: - ansible-version: [stable-2.11, stable-2.12, stable-2.13, stable-2.14] + ansible-version: [stable-2.11, stable-2.12, stable-2.13, stable-2.14, devel] steps: - - name: Set up Python 3.9 + - name: Set up Python uses: actions/setup-python@v1 with: # it is just required to run that once as "ansible-test sanity" in the docker image @@ -139,7 +139,7 @@ jobs: fail-fast: false matrix: python-version: [3.9, '3.10'] - ansible-version: [stable-2.13, stable-2.14] + ansible-version: [stable-2.12, stable-2.13, stable-2.14] steps: # Important: This sets up your GITHUB_WORKSPACE environment variable diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2d0186a2d..8816fba9f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,37 @@ Dell OpenManage Ansible Modules Release Notes .. contents:: Topics +v7.4.0 +====== + +Release Summary +--------------- + +- Role to support the Import server configuration profile, Manage iDRAC power states, Manage iDRAC certificate, + Gather facts from iDRAC and Deploy operating system is added. +- Plugin OME inventory is enhanced to support the environment variables for the input parameters. + + +Known Issues +------------ + +- idrac_os_deployment- Issue(260496) - OS installation will support only NFS and CIFS share to store the custom ISO in the destination_path, HTTP/HTTPS/FTP not supported +- idrac_redfish_storage_contoller - Issue(256164) - If incorrect value is provided for one of the attributes in the provided attribute list for controller configuration, then this module does not exit with error. +- idrac_user - Issue(192043) The module may error out with the message ``Unable to perform the import or export operation because there are pending attribute changes or a configuration job is in progress``. Wait for the job to complete and run the task again. +- ome_application_alerts_syslog - Issue(215374) - The module does not provide a proper error message if the destination_address is more than 255 characters. +- ome_device_network_services - Issue(212681) - The module does not provide a proper error message if unsupported values are provided for the following parameters- port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. +- ome_device_power_settings - Issue(212679) - The module displays the following message if the value provided for the parameter ``power_cap`` is not within the supported range of 0 to 32767, ``Unable to complete the request because PowerCap does not exist or is not applicable for the resource URI.`` +- ome_smart_fabric_uplink - Issue(186024) - Despite the module supported by OpenManage Enterprise Modular, it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, the existing uplink is modified. + +New Roles +--------- + +- dellemc.openmanage.idrac_certificate - Role to manage the iDRAC certificates - generate CSR, import/export certificates, and reset configuration - for PowerEdge servers. +- dellemc.openmanage.idrac_gather_facts - Role to gather facts from the iDRAC Server. +- dellemc.openmanage.idrac_import_server_config_profile - Role to import iDRAC Server Configuration Profile (SCP). +- dellemc.openmanage.idrac_os_deployment - Role to deploy specified operating system and version on the servers. +- dellemc.openmanage.idrac_server_powerstate - Role to manage the different power states of the specified device. + v7.3.0 ====== @@ -457,7 +488,7 @@ Support to provide custom or organizational CA signed certificate for SSL valida Major Changes ------------- -- All modules can read custom or organizational CA signed certificate from the environment variables. Please refer to `SSL Certificate Validation ` _ section in the `README.md ` _ for modification to existing playbooks or setting environment variable. +- All modules can read custom or organizational CA signed certificate from the environment variables. Please refer to `SSL Certificate Validation ` _ section in the `README.md ` _ for modification to existing playbooks or setting environment variable. Bugfixes -------- diff --git a/README.md b/README.md index 9f94897b7..c34f66e0e 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,12 @@ OpenManage Ansible Modules simplifies and automates provisioning, deployment, an ## Supported Platforms * iDRAC7 based Dell PowerEdge Servers with firmware versions 2.63.60.62 and above. * iDRAC8 based Dell PowerEdge Servers with firmware versions 2.82.82.82 and above. - * iDRAC9 based Dell PowerEdge Servers with firmware versions 6.00.30.00 and above. - * Dell OpenManage Enterprise versions 3.8.3 and above. + * iDRAC9 based Dell PowerEdge Servers with firmware versions 6.10.00.00 and above. + * Dell OpenManage Enterprise versions 3.9.2 and above. * Dell OpenManage Enterprise Modular versions 1.40.20 and above. ## Prerequisites - * [Ansible Core >= 2.13.7 and 2.14.1](https://github.com/ansible/ansible) + * [Ansible Core >= 2.13.8 and 2.14.3](https://github.com/ansible/ansible) * Python >= 3.9.6 * To run the iDRAC modules, install OpenManage Python Software Development Kit (OMSDK) using either ```pip install omsdk --upgrade``` or ```pip install -r requirements.txt```. diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 4b92060a1..c2108e448 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -2,1226 +2,1232 @@ ancestor: null releases: 2.1.0: changes: - release_summary: - The `Dell OpenManage Ansible Modules `_ + release_summary: The `Dell OpenManage Ansible Modules `_ are available on Ansible Galaxy as a collection. - release_date: "2020-07-29" + release_date: '2020-07-29' 2.1.1: changes: deprecated_features: - - The dellemc_configure_bios module is deprecated and replaced with the idrac_bios - module. - - The dellemc_configure_idrac_network module is deprecated and replaced with - the idrac_network module. - - The dellemc_configure_idrac_timezone module is deprecated and replaced with - the idrac_timezone_ntp module. - - The dellemc_delete_lc_job and dellemc_delete_lc_job_queue modules are deprecated - and replaced with the idrac_lifecycle_controller_jobs module. - - The dellemc_export_lc_logs module is deprecated and replaced with the idrac_lifecycle_controller_logs - module. - - The dellemc_get_lc_job_status module is deprecated and replaced with the idrac_lifecycle_controller_job_status_info - module. - - The dellemc_get_lcstatus module is deprecated and replaced with the idrac_lifecycle_controller_status_info - module. - - The dellemc_idrac_reset module is deprecated and replaced with the idrac_reset - module. - - The dellemc_setup_idrac_syslog module is deprecated and replaced with the - idrac_syslog module. + - The dellemc_configure_bios module is deprecated and replaced with the idrac_bios + module. + - The dellemc_configure_idrac_network module is deprecated and replaced with + the idrac_network module. + - The dellemc_configure_idrac_timezone module is deprecated and replaced with + the idrac_timezone_ntp module. + - The dellemc_delete_lc_job and dellemc_delete_lc_job_queue modules are deprecated + and replaced with the idrac_lifecycle_controller_jobs module. + - The dellemc_export_lc_logs module is deprecated and replaced with the idrac_lifecycle_controller_logs + module. + - The dellemc_get_lc_job_status module is deprecated and replaced with the idrac_lifecycle_controller_job_status_info + module. + - The dellemc_get_lcstatus module is deprecated and replaced with the idrac_lifecycle_controller_status_info + module. + - The dellemc_idrac_reset module is deprecated and replaced with the idrac_reset + module. + - The dellemc_setup_idrac_syslog module is deprecated and replaced with the + idrac_syslog module. major_changes: - - Standardization of ten iDRAC ansible modules based on ansible guidelines. - - Support for OpenManage Enterprise Modular. + - Standardization of ten iDRAC ansible modules based on ansible guidelines. + - Support for OpenManage Enterprise Modular. release_summary: Support for OpenManage Enterprise Modular and other enhancements. modules: - - description: Configure the BIOS attributes - name: idrac_bios - namespace: "" - - description: Get the status of a Lifecycle Controller job - name: idrac_lifecycle_controller_job_status_info - namespace: "" - - description: Delete the Lifecycle Controller Jobs - name: idrac_lifecycle_controller_jobs - namespace: "" - - description: Export Lifecycle Controller logs to a network share or local path. - name: idrac_lifecycle_controller_logs - namespace: "" - - description: Get the status of the Lifecycle Controller - name: idrac_lifecycle_controller_status_info - namespace: "" - - description: Configures the iDRAC network attributes - name: idrac_network - namespace: "" - - description: Reset iDRAC - name: idrac_reset - namespace: "" - - description: Enable or disable the syslog on iDRAC - name: idrac_syslog - namespace: "" - - description: Configures time zone and NTP on iDRAC - name: idrac_timezone_ntp - namespace: "" - release_date: "2020-08-26" + - description: Configure the BIOS attributes + name: idrac_bios + namespace: '' + - description: Get the status of a Lifecycle Controller job + name: idrac_lifecycle_controller_job_status_info + namespace: '' + - description: Delete the Lifecycle Controller Jobs + name: idrac_lifecycle_controller_jobs + namespace: '' + - description: Export Lifecycle Controller logs to a network share or local path. + name: idrac_lifecycle_controller_logs + namespace: '' + - description: Get the status of the Lifecycle Controller + name: idrac_lifecycle_controller_status_info + namespace: '' + - description: Configures the iDRAC network attributes + name: idrac_network + namespace: '' + - description: Reset iDRAC + name: idrac_reset + namespace: '' + - description: Enable or disable the syslog on iDRAC + name: idrac_syslog + namespace: '' + - description: Configures time zone and NTP on iDRAC + name: idrac_timezone_ntp + namespace: '' + release_date: '2020-08-26' 2.1.2: changes: bugfixes: - - Documentation improvement request `#140 `_ - - Executing dellemc_configure_idrac_users twice fails the second attempt `#100 - `_ - - dellemc_change_power_state fails if host is already on `#132 `_ - - dellemc_change_power_state not idempotent `#115 `_ - - dellemc_configure_idrac_users error `#26 `_ - - dellemc_configure_idrac_users is unreliable - errors `#113 `_ - - idrac_server_config_profile improvement requested (request) `#137 `_ - - ome_firmware_catalog.yml example errors `#145 `_ + - Documentation improvement request `#140 `_ + - Executing dellemc_configure_idrac_users twice fails the second attempt `#100 + `_ + - dellemc_change_power_state fails if host is already on `#132 `_ + - dellemc_change_power_state not idempotent `#115 `_ + - dellemc_configure_idrac_users error `#26 `_ + - dellemc_configure_idrac_users is unreliable - errors `#113 `_ + - idrac_server_config_profile improvement requested (request) `#137 `_ + - ome_firmware_catalog.yml example errors `#145 `_ deprecated_features: - - The dellemc_change_power_state module is deprecated and replaced with the - redfish_powerstate module. - - The dellemc_configure_idrac_users module is deprecated and replaced with the - idrac_user module. + - The dellemc_change_power_state module is deprecated and replaced with the + redfish_powerstate module. + - The dellemc_configure_idrac_users module is deprecated and replaced with the + idrac_user module. minor_changes: - - The idrac_server_config_profile module supports a user provided file name - for an export operation. - release_summary: - The dellemc_change_power_state and dellemc_configure_idrac_users + - The idrac_server_config_profile module supports a user provided file name + for an export operation. + release_summary: The dellemc_change_power_state and dellemc_configure_idrac_users modules are standardized as per ansible guidelines. 8 GitHub issues are fixed. modules: - - description: Configure settings for user accounts - name: idrac_user - namespace: "" - - description: Manage device power state - name: redfish_powerstate - namespace: "" - release_date: "2020-09-23" + - description: Configure settings for user accounts + name: idrac_user + namespace: '' + - description: Manage device power state + name: redfish_powerstate + namespace: '' + release_date: '2020-09-23' 2.1.3: changes: - release_summary: - Network configuration service related modules ome_network_vlan, + release_summary: Network configuration service related modules ome_network_vlan, ome_network_port_breakout and ome_network_vlan_info are added. modules: - - description: - This module allows to automate the port portioning or port breakout - to logical sub ports - name: ome_network_port_breakout - namespace: "" - - description: Create, modify & delete a VLAN - name: ome_network_vlan - namespace: "" - - description: - Retrieves the information about networks VLAN(s) present in OpenManage - Enterprise - name: ome_network_vlan_info - namespace: "" - release_date: "2020-10-29" + - description: This module allows to automate the port portioning or port breakout + to logical sub ports + name: ome_network_port_breakout + namespace: '' + - description: Create, modify & delete a VLAN + name: ome_network_vlan + namespace: '' + - description: Retrieves the information about networks VLAN(s) present in OpenManage + Enterprise + name: ome_network_vlan_info + namespace: '' + release_date: '2020-10-29' 2.1.4: changes: known_issues: - - "Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation - of multiple uplinks of the same name even though this is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified." - release_summary: - Fabric management related modules ome_smart_fabric and ome_smart_fabric_uplink + - 'Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation + of multiple uplinks of the same name even though this is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified.' + release_summary: Fabric management related modules ome_smart_fabric and ome_smart_fabric_uplink are added. modules: - - description: Create, modify or delete a fabric on OpenManage Enterprise Modular - name: ome_smart_fabric - namespace: "" - - description: - Create, modify or delete a uplink for a fabric on OpenManage Enterprise - Modular - name: ome_smart_fabric_uplink - namespace: "" - release_date: "2020-11-25" + - description: Create, modify or delete a fabric on OpenManage Enterprise Modular + name: ome_smart_fabric + namespace: '' + - description: Create, modify or delete a uplink for a fabric on OpenManage Enterprise + Modular + name: ome_smart_fabric_uplink + namespace: '' + release_date: '2020-11-25' 2.1.5: changes: bugfixes: - - Identity pool does not reset when a network VLAN is added to a template in - the ome_template_network_vlan module. `#169 `_ - - Missing parameter added in ome_smart_fabric_uplink module documenation. `#181 - `_ + - Identity pool does not reset when a network VLAN is added to a template in + the ome_template_network_vlan module. `#169 `_ + - Missing parameter added in ome_smart_fabric_uplink module documenation. `#181 + `_ known_issues: - - "Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation - of multiple uplinks of the same name even though this is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified." - - "Issue 2(187956): If an invalid job_id is provided, idrac_lifecycle_controller_job_status_info - returns an error message. This error message does not contain information - about the exact issue with the invalid job_id." - - "Issue 3(188267): While updating the iDRAC firmware, the idrac_firmware module - completes execution before the firmware update job is completed. An incorrect - message is displayed in the task output as 'DRAC WSMAN endpoint returned - HTTP code '400' Reason 'Bad Request''. This issue may occur if the target - iDRAC firmware version is less than 3.30.30.30" + - 'Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation + of multiple uplinks of the same name even though this is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified.' + - 'Issue 2(187956): If an invalid job_id is provided, idrac_lifecycle_controller_job_status_info + returns an error message. This error message does not contain information + about the exact issue with the invalid job_id.' + - 'Issue 3(188267): While updating the iDRAC firmware, the idrac_firmware module + completes execution before the firmware update job is completed. An incorrect + message is displayed in the task output as ''DRAC WSMAN endpoint returned + HTTP code ''400'' Reason ''Bad Request''''. This issue may occur if the target + iDRAC firmware version is less than 3.30.30.30' minor_changes: - - The idrac_server_config_profile module supports IPv6 address format. - release_summary: - The idrac_firmware module is enhanced to include checkmode + - The idrac_server_config_profile module supports IPv6 address format. + release_summary: The idrac_firmware module is enhanced to include checkmode support and job tracking. - release_date: "2020-12-30" + release_date: '2020-12-30' 3.0.0: changes: bugfixes: - - GitHub issue fix - Module dellemc_idrac_storage_volume.py broken. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/212) - - GitHub issue fix - ome_smart_fabric Fabric management is not supported on - the specified system. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/179) - - "Known issue fix #187956: If an invalid job_id is provided, the idrac_lifecycle_controller_job_status_info - module returns an error message with the description of the issue." - - "Known issue fix #188267: No error message is displayed when the target iDRAC - with firmware version less than 3.30.30.30 is updated." - - Sanity fixes as per ansible guidelines to all modules. + - GitHub issue fix - Module dellemc_idrac_storage_volume.py broken. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/212) + - GitHub issue fix - ome_smart_fabric Fabric management is not supported on + the specified system. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/179) + - 'Known issue fix #187956: If an invalid job_id is provided, the idrac_lifecycle_controller_job_status_info + module returns an error message with the description of the issue.' + - 'Known issue fix #188267: No error message is displayed when the target iDRAC + with firmware version less than 3.30.30.30 is updated.' + - Sanity fixes as per ansible guidelines to all modules. deprecated_features: - - The ``dellemc_get_firmware_inventory`` module is deprecated and replaced with - ``idrac_firmware_info``. - - The ``dellemc_get_system_inventory`` module is deprecated and replaced with - ``idrac_system_info``. + - The ``dellemc_get_firmware_inventory`` module is deprecated and replaced with + ``idrac_firmware_info``. + - The ``dellemc_get_system_inventory`` module is deprecated and replaced with + ``idrac_system_info``. known_issues: - - "Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation - of multiple uplinks of the same name even though this is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified." + - 'Issue 1(186024): ome_smart_fabric_uplink module does not allow the creation + of multiple uplinks of the same name even though this is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified.' major_changes: - - Removed the existing deprecated modules. + - Removed the existing deprecated modules. minor_changes: - - Coding Guidelines, Contributor Agreement, and Code of Conduct files are added - to the collection. - - New deprecation changes for ``dellemc_get_system_inventory`` and ``dellemc_get_firmware_inventory`` - ignored for ansible 2.9 sanity test. - - The modules are standardized as per ansible guidelines. - release_summary: - Deprecations, issue fixes, and standardization of modules as + - Coding Guidelines, Contributor Agreement, and Code of Conduct files are added + to the collection. + - New deprecation changes for ``dellemc_get_system_inventory`` and ``dellemc_get_firmware_inventory`` + ignored for ansible 2.9 sanity test. + - The modules are standardized as per ansible guidelines. + release_summary: Deprecations, issue fixes, and standardization of modules as per ansible guidelines. - release_date: "2021-01-25" + release_date: '2021-01-25' 3.1.0: changes: bugfixes: - - ome_firmware_baseline_compliance_info - OMEnt firmware baseline compliance - info pagination support added (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/171) - - ome_network_proxy - OMEnt network proxy check mode support added (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/187) + - ome_firmware_baseline_compliance_info - OMEnt firmware baseline compliance + info pagination support added (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/171) + - ome_network_proxy - OMEnt network proxy check mode support added (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/187) known_issues: - - ome_smart_fabric - Issue(185322) Only three design types are supported by - OpenManage Enterprise Modular but the module successfully creates a fabric - when the design type is not supported. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - ome_smart_fabric - Issue(185322) Only three design types are supported by + OpenManage Enterprise Modular but the module successfully creates a fabric + when the design type is not supported. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. release_summary: OpenManage Enterprise profiles management support added. modules: - - description: - Create, modify, delete, assign, unassign and migrate a profile - on OpenManage Enterprise - name: ome_profile - namespace: "" - release_date: "2021-02-24" + - description: Create, modify, delete, assign, unassign and migrate a profile + on OpenManage Enterprise + name: ome_profile + namespace: '' + release_date: '2021-02-24' 3.2.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_configuration_compliance_info - Issue(195592) Module may error out with - the message ``unable to process the request because an error occurred``. If - the issue persists, report it to the system administrator. - - ome_smart_fabric - Issue(185322) Only three design types are supported by - OpenManage Enterprise Modular but the module successfully creates a fabric - when the design type is not supported. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_configuration_compliance_info - Issue(195592) Module may error out with + the message ``unable to process the request because an error occurred``. If + the issue persists, report it to the system administrator. + - ome_smart_fabric - Issue(185322) Only three design types are supported by + OpenManage Enterprise Modular but the module successfully creates a fabric + when the design type is not supported. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. minor_changes: - - ome_template - Allows to deploy a template on device groups. + - ome_template - Allows to deploy a template on device groups. release_summary: Configuration compliance related modules added modules: - - description: - Create, modify, and delete a configuration compliance baseline - and remediate non-compliant devices on OpenManage Enterprise - name: ome_configuration_compliance_baseline - namespace: "" - - description: Device compliance report for devices managed in OpenManage Enterprise - name: ome_configuration_compliance_info - namespace: "" - release_date: "2021-03-24" + - description: Create, modify, and delete a configuration compliance baseline + and remediate non-compliant devices on OpenManage Enterprise + name: ome_configuration_compliance_baseline + namespace: '' + - description: Device compliance report for devices managed in OpenManage Enterprise + name: ome_configuration_compliance_info + namespace: '' + release_date: '2021-03-24' 3.3.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_configuration_compliance_info - Issue(195592) Module may error out with - the message ``unable to process the request because an error occurred``. If - the issue persists, report it to the system administrator. - - ome_smart_fabric - Issue(185322) Only three design types are supported by - OpenManage Enterprise Modular but the module successfully creates a fabric - when the design type is not supported. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_configuration_compliance_info - Issue(195592) Module may error out with + the message ``unable to process the request because an error occurred``. If + the issue persists, report it to the system administrator. + - ome_smart_fabric - Issue(185322) Only three design types are supported by + OpenManage Enterprise Modular but the module successfully creates a fabric + when the design type is not supported. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. minor_changes: - - ome_firmware_baseline - Allows to retrieve the device even if it not in the - first 50 device IDs - release_summary: - OpenManage Enterprise device group and device discovery support + - ome_firmware_baseline - Allows to retrieve the device even if it not in the + first 50 device IDs + release_summary: OpenManage Enterprise device group and device discovery support added modules: - - description: Add devices to a static device group on OpenManage Enterprise - name: ome_device_group - namespace: "" - - description: Create, modify, or delete a discovery job on OpenManage Enterprise - name: ome_discovery - namespace: "" - release_date: "2021-04-28" + - description: Add devices to a static device group on OpenManage Enterprise + name: ome_device_group + namespace: '' + - description: Create, modify, or delete a discovery job on OpenManage Enterprise + name: ome_discovery + namespace: '' + release_date: '2021-04-28' 3.4.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. major_changes: - - ome_firmware_baseline - Module supports check mode, and allows the modification - and deletion of firmware baselines. - - ome_firmware_catalog - Module supports check mode, and allows the modification - and deletion of firmware catalogs. + - ome_firmware_baseline - Module supports check mode, and allows the modification + and deletion of firmware baselines. + - ome_firmware_catalog - Module supports check mode, and allows the modification + and deletion of firmware catalogs. minor_changes: - - ome_firmware_catalog - Added support for repositories available on the Dell - support site. - - ome_template_network_vlan - Added the input option which allows to apply the - modified VLAN settings immediately on the associated modular-system servers. - release_summary: - OpenManage Enterprise firmware baseline and firmware catalog + - ome_firmware_catalog - Added support for repositories available on the Dell + support site. + - ome_template_network_vlan - Added the input option which allows to apply the + modified VLAN settings immediately on the associated modular-system servers. + release_summary: OpenManage Enterprise firmware baseline and firmware catalog modules updated to support checkmode. - release_date: "2021-05-26" + release_date: '2021-05-26' 3.5.0: changes: bugfixes: - - Handled invalid share and unused imports cleanup for iDRAC modules (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/268) + - Handled invalid share and unused imports cleanup for iDRAC modules (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/268) known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. major_changes: - - idrac_server_config_profile - Added support for exporting and importing Server - Configuration Profile through HTTP/HTTPS share. - - ome_device_group - Added support for adding devices to a group using the IP - addresses of the devices and group ID. + - idrac_server_config_profile - Added support for exporting and importing Server + Configuration Profile through HTTP/HTTPS share. + - ome_device_group - Added support for adding devices to a group using the IP + addresses of the devices and group ID. release_summary: Support for managing static device groups on OpenManage Enterprise. modules: - - description: Manages static device groups on OpenManage Enterprise - name: ome_groups - namespace: "" - release_date: "2021-06-28" + - description: Manages static device groups on OpenManage Enterprise + name: ome_groups + namespace: '' + release_date: '2021-06-28' 3.6.0: changes: bugfixes: - - dellemc_idrac_storage_volume - Module fails if the BlockSize, FreeSize, or - Size state of the physical disk is set to "Not Available". + - dellemc_idrac_storage_volume - Module fails if the BlockSize, FreeSize, or + Size state of the physical disk is set to "Not Available". known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. - release_summary: - Support for configuring device slot name and export SupportAssist + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. + release_summary: Support for configuring device slot name and export SupportAssist device collections from OpenManage Enterprise and OpenManage Enterprise Modular. modules: - - description: Rename sled slots on OpenManage Enterprise Modular - name: ome_chassis_slots - namespace: "" - - description: Export technical support logs(TSR) to network share location - name: ome_diagnostics - namespace: "" - release_date: "2021-07-28" + - description: Rename sled slots on OpenManage Enterprise Modular + name: ome_chassis_slots + namespace: '' + - description: Export technical support logs(TSR) to network share location + name: ome_diagnostics + namespace: '' + release_date: '2021-07-28' 4.0.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though this - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. - release_summary: - Support for configuring active directory user group on OpenManage + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though this + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. + release_summary: Support for configuring active directory user group on OpenManage Enterprise and OpenManage Enterprise Modular. modules: - - description: - Configure Active Directory groups to be used with Directory Services - on OpenManage Enterprise and OpenManage Enterprise Modular - name: ome_active_directory - namespace: "" - - description: - Create, modify, or delete an Active Directory user group on OpenManage - Enterprise and OpenManage Enterprise Modular - name: ome_domain_user_groups - namespace: "" - release_date: "2021-08-27" + - description: Configure Active Directory groups to be used with Directory Services + on OpenManage Enterprise and OpenManage Enterprise Modular + name: ome_active_directory + namespace: '' + - description: Create, modify, or delete an Active Directory user group on OpenManage + Enterprise and OpenManage Enterprise Modular + name: ome_domain_user_groups + namespace: '' + release_date: '2021-08-27' 4.1.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though it - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though it + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. major_changes: - - ome_firmware - Added option to stage the firmware update and support for selecting - components and devices for baseline-based firmware update. + - ome_firmware - Added option to stage the firmware update and support for selecting + components and devices for baseline-based firmware update. minor_changes: - - ome_template_network_vlan - Enabled check_mode support. - release_summary: - Support for Redfish event subscriptions and enhancements to + - ome_template_network_vlan - Enabled check_mode support. + release_summary: Support for Redfish event subscriptions and enhancements to ome_firmware module. modules: - - description: Manage Redfish Subscriptions - name: redfish_event_subscription - namespace: "" - release_date: "2021-09-28" + - description: Manage Redfish Subscriptions + name: redfish_event_subscription + namespace: '' + release_date: '2021-09-28' 4.2.0: changes: known_issues: - - idrac_user - Issue(192043) Module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_device_power_settings - Issue(212679) The ome_device_power_settings module - errors out with the following message if the value provided for the parameter - ``power_cap`` is not within the supported range of 0 to 32767, ``Unable to - complete the request because PowerCap does not exist or is not applicable - for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does - not allow the creation of multiple uplinks of the same name even though it - is supported by OpenManage Enterprise Modular. If an uplink is created using - the same name as an existing uplink, the existing uplink is modified. - release_summary: - Support to configure OME Modular devices network, power, and + - idrac_user - Issue(192043) Module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_device_power_settings - Issue(212679) The ome_device_power_settings module + errors out with the following message if the value provided for the parameter + ``power_cap`` is not within the supported range of 0 to 32767, ``Unable to + complete the request because PowerCap does not exist or is not applicable + for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) ome_smart_fabric_uplink module does + not allow the creation of multiple uplinks of the same name even though it + is supported by OpenManage Enterprise Modular. If an uplink is created using + the same name as an existing uplink, the existing uplink is modified. + release_summary: Support to configure OME Modular devices network, power, and location settings. modules: - - description: Configure device location settings on OpenManage Enterprise Modular - name: ome_device_location - namespace: "" - - description: - Configure network settings of devices on OpenManage Enterprise - Modular - name: ome_device_mgmt_network - namespace: "" - - description: Configure chassis power settings on OpenManage Enterprise Modular - name: ome_device_power_settings - namespace: "" - release_date: "2021-10-27" + - description: Configure device location settings on OpenManage Enterprise Modular + name: ome_device_location + namespace: '' + - description: Configure network settings of devices on OpenManage Enterprise + Modular + name: ome_device_mgmt_network + namespace: '' + - description: Configure chassis power settings on OpenManage Enterprise Modular + name: ome_device_power_settings + namespace: '' + release_date: '2021-10-27' 4.3.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module errors out with the - following message if the value provided for the parameter ``power_cap`` is - not within the supported range of 0 to 32767, ``Unable to complete the request - because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. - release_summary: - Support to configure network services, syslog forwarding, and + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module errors out with the + following message if the value provided for the parameter ``power_cap`` is + not within the supported range of 0 to 32767, ``Unable to complete the request + because PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. + release_summary: Support to configure network services, syslog forwarding, and SMTP settings. modules: - - description: This module allows to configure SMTP or email configurations - name: ome_application_alerts_smtp - namespace: "" - - description: - Configure syslog forwarding settings on OpenManage Enterprise and - OpenManage Enterprise Modular - name: ome_application_alerts_syslog - namespace: "" - - description: - Configure chassis network services settings on OpenManage Enterprise - Modular - name: ome_device_network_services - namespace: "" - release_date: "2021-11-26" + - description: This module allows to configure SMTP or email configurations + name: ome_application_alerts_smtp + namespace: '' + - description: Configure syslog forwarding settings on OpenManage Enterprise and + OpenManage Enterprise Modular + name: ome_application_alerts_syslog + namespace: '' + - description: Configure chassis network services settings on OpenManage Enterprise + Modular + name: ome_device_network_services + namespace: '' + release_date: '2021-11-26' 4.4.0: changes: bugfixes: - - ome_device_location - The issue that applies values of the location settings - only in lowercase is fixed (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/341) + - ome_device_location - The issue that applies values of the location settings + only in lowercase is fixed (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/341) known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module errors out with the - following message if the value provided for the parameter ``power_cap`` is - not within the supported range of 0 to 32767, ``Unable to complete the request - because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module errors out with the + following message if the value provided for the parameter ``power_cap`` is + not within the supported range of 0 to 32767, ``Unable to complete the request + because PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. minor_changes: - - ome_firmware - The module is enhanced to support check mode and idempotency - (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/274) - - ome_template - An example task is added to create a compliance template from - reference device (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/339) - release_summary: - Support to configure login security, session inactivity timeout, + - ome_firmware - The module is enhanced to support check mode and idempotency + (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/274) + - ome_template - An example task is added to create a compliance template from + reference device (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/339) + release_summary: Support to configure login security, session inactivity timeout, and local access settings. modules: - - description: - This module allows you to configure the session inactivity timeout - settings - name: ome_application_network_settings - namespace: "" - - description: Configure the login security properties - name: ome_application_security_settings - namespace: "" - - description: Configure local access settings on OpenManage Enterprise Modular - name: ome_device_local_access_configuration - namespace: "" - release_date: "2021-12-24" + - description: This module allows you to configure the session inactivity timeout + settings + name: ome_application_network_settings + namespace: '' + - description: Configure the login security properties + name: ome_application_security_settings + namespace: '' + - description: Configure local access settings on OpenManage Enterprise Modular + name: ome_device_local_access_configuration + namespace: '' + release_date: '2021-12-24' 5.0.0: changes: breaking_changes: - - HTTPS SSL certificate validation is a **breaking change** and will require - modification in the existing playbooks. Please refer to `SSL Certificate Validation - `_ - section in the `README.md `_ - for modification to existing playbooks. + - HTTPS SSL certificate validation is a **breaking change** and will require + modification in the existing playbooks. Please refer to `SSL Certificate Validation + `_ + section in the `README.md `_ + for modification to existing playbooks. bugfixes: - - idrac_bios - The issue while configuring boot sources is fixed (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/347) + - idrac_bios - The issue while configuring boot sources is fixed (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/347) known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module errors out with the - following message if the value provided for the parameter ``power_cap`` is - not within the supported range of 0 to 32767, ``Unable to complete the request - because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module errors out with the + following message if the value provided for the parameter ``power_cap`` is + not within the supported range of 0 to 32767, ``Unable to complete the request + because PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - All modules now support SSL over HTTPS and socket level timeout. + - All modules now support SSL over HTTPS and socket level timeout. release_summary: HTTPS SSL support for all modules and quick deploy settings. modules: - - description: Configure Quick Deploy settings on OpenManage Enterprise Modular - name: ome_device_quick_deploy - namespace: "" - release_date: "2022-01-27" + - description: Configure Quick Deploy settings on OpenManage Enterprise Modular + name: ome_device_quick_deploy + namespace: '' + release_date: '2022-01-27' 5.0.1: changes: bugfixes: - - All playbooks require modification because the validate_certs argument is - set to True by default (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/357) - - The ome_application_network_time and ome_application_network_proxy modules - are breaking due to the changes introduced for SSL validation.(https://github.com/dell/dellemc-openmanage-ansible-modules/issues/360) + - All playbooks require modification because the validate_certs argument is + set to True by default (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/357) + - The ome_application_network_time and ome_application_network_proxy modules + are breaking due to the changes introduced for SSL validation.(https://github.com/dell/dellemc-openmanage-ansible-modules/issues/360) known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module errors out with the - following message if the value provided for the parameter ``power_cap`` is - not within the supported range of 0 to 32767, ``Unable to complete the request - because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module errors out with the + following message if the value provided for the parameter ``power_cap`` is + not within the supported range of 0 to 32767, ``Unable to complete the request + because PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - All modules can read custom or organizational CA signed certificate from the environment variables. - Please refer to `SSL Certificate Validation - ` - _ section in the `README.md ` - _ for modification to existing playbooks or setting environment variable. - release_summary: - Support to provide custom or organizational CA signed certificate + - All modules can read custom or organizational CA signed certificate from the + environment variables. Please refer to `SSL Certificate Validation ` + _ section in the `README.md ` _ for modification + to existing playbooks or setting environment variable. + release_summary: Support to provide custom or organizational CA signed certificate for SSL validation from the environment variable. - release_date: "2022-02-11" + release_date: '2022-02-11' 5.1.0: changes: bugfixes: - - idrac_firmware - Issue (220130) The socket.timout issue that occurs during - the wait_for_job_completion() job is fixed. + - idrac_firmware - Issue (220130) The socket.timout issue that occurs during + the wait_for_job_completion() job is fixed. known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module errors out with the - following message if the value provided for the parameter ``power_cap`` is - not within the supported range of 0 to 32767, ``Unable to complete the request - because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module errors out with the + following message if the value provided for the parameter ``power_cap`` is + not within the supported range of 0 to 32767, ``Unable to complete the request + because PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. minor_changes: - - ome_application_network_address - The module is enhanced to support check - mode and idempotency. - - ome_device_info - The module is enhanced to return a blank list when devices - or baselines are not present in the system. - - ome_firmware_baseline_compliance_info - The module is enhanced to return a - blank list when devices or baselines are not present in the system. - - ome_firmware_baseline_info - The module is enhanced to return a blank list - when devices or baselines are not present in the system. - - ome_identity_pool - The iSCSI Initiator and Initiator IP Pool attributes are - not mandatory to create an identity pool. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/329) - - ome_identity_pool - The module is enhanced to support check mode and idempotency. - (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/328) - - ome_template_identity_pool - The module is enhanced to support check mode - and idempotency. - - redfish_event_subscription - The module is enhanced to support check mode - and idempotency. - release_summary: - Support for OpenManage Enterprise Modular server interface + - ome_application_network_address - The module is enhanced to support check + mode and idempotency. + - ome_device_info - The module is enhanced to return a blank list when devices + or baselines are not present in the system. + - ome_firmware_baseline_compliance_info - The module is enhanced to return a + blank list when devices or baselines are not present in the system. + - ome_firmware_baseline_info - The module is enhanced to return a blank list + when devices or baselines are not present in the system. + - ome_identity_pool - The iSCSI Initiator and Initiator IP Pool attributes are + not mandatory to create an identity pool. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/329) + - ome_identity_pool - The module is enhanced to support check mode and idempotency. + (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/328) + - ome_template_identity_pool - The module is enhanced to support check mode + and idempotency. + - redfish_event_subscription - The module is enhanced to support check mode + and idempotency. + release_summary: Support for OpenManage Enterprise Modular server interface management. modules: - - description: - Retrieves the information of server interface profile on OpenManage - Enterprise Modular. - name: ome_server_interface_profile_info - namespace: "" - - description: Configures server interface profiles on OpenManage Enterprise Modular. - name: ome_server_interface_profiles - namespace: "" - release_date: "2022-02-24" + - description: Retrieves the information of server interface profile on OpenManage + Enterprise Modular. + name: ome_server_interface_profile_info + namespace: '' + - description: Configures server interface profiles on OpenManage Enterprise Modular. + name: ome_server_interface_profiles + namespace: '' + release_date: '2022-02-24' 5.2.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_console_preferences - Issue(224690) - The module does not - display a proper error message when an unsupported value is provided for the - parameters report_row_limit, email_sender_settings, and metric_collection_settings, - and the value is applied on OpenManage Enterprise. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_console_preferences - Issue(224690) - The module does not + display a proper error message when an unsupported value is provided for the + parameters report_row_limit, email_sender_settings, and metric_collection_settings, + and the value is applied on OpenManage Enterprise. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. minor_changes: - - idrac_redfish_storage_controller - This module is enhanced to support the - following settings with check mode and idempotency - UnassignSpare, EnableControllerEncryption, - BlinkTarget, UnBlinkTarget, ConvertToRAID, ConvertToNonRAID, ChangePDStateToOnline, - ChangePDStateToOffline. - - ome_diagnostics - The module is enhanced to support check mode and idempotency. - (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/345) - - ome_diagnostics - This module is enhanced to extract log from lead chassis. - (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/310) - - ome_profile - The module is enhanced to support check mode and idempotency. - - ome_profile - The module is enhanced to support modifying a profile based - on the attribute names instead of the ID. - - ome_template - The module is enhanced to support check mode and idempotency. - (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/255) - - ome_template - The module is enhanced to support modifying a template based - on the attribute names instead of the ID. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/358) + - idrac_redfish_storage_controller - This module is enhanced to support the + following settings with check mode and idempotency - UnassignSpare, EnableControllerEncryption, + BlinkTarget, UnBlinkTarget, ConvertToRAID, ConvertToNonRAID, ChangePDStateToOnline, + ChangePDStateToOffline. + - ome_diagnostics - The module is enhanced to support check mode and idempotency. + (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/345) + - ome_diagnostics - This module is enhanced to extract log from lead chassis. + (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/310) + - ome_profile - The module is enhanced to support check mode and idempotency. + - ome_profile - The module is enhanced to support modifying a profile based + on the attribute names instead of the ID. + - ome_template - The module is enhanced to support check mode and idempotency. + (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/255) + - ome_template - The module is enhanced to support modifying a template based + on the attribute names instead of the ID. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/358) release_summary: Support to configure console preferences on OpenManage Enterprise. modules: - - description: Configures console preferences on OpenManage Enterprise. - name: ome_application_console_preferences - namespace: "" - release_date: "2022-03-29" + - description: Configures console preferences on OpenManage Enterprise. + name: ome_application_console_preferences + namespace: '' + release_date: '2022-03-29' 5.3.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_console_preferences - Issue(224690) - The module does not - display a proper error message when an unsupported value is provided for the - parameters report_row_limit, email_sender_settings, and metric_collection_settings, - and the value is applied on OpenManage Enterprise. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_console_preferences - Issue(224690) - The module does not + display a proper error message when an unsupported value is provided for the + parameters report_row_limit, email_sender_settings, and metric_collection_settings, + and the value is applied on OpenManage Enterprise. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. minor_changes: - - ome_diagnostics - Added "supportassist_collection" as a choice for the log_type - argument to export SupportAssist logs. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/309) - - ome_diagnostics - The module is enhanced to support debug logs. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/308) - - ome_smart_fabric_uplink - The module is enhanced to support idempotency. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/253) - - redfish_storage_volume - The module is enhanced to support check mode and - idempotency. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/245) - release_summary: - Added check mode and idempotency support for redfish_storage_volume + - ome_diagnostics - Added "supportassist_collection" as a choice for the log_type + argument to export SupportAssist logs. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/309) + - ome_diagnostics - The module is enhanced to support debug logs. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/308) + - ome_smart_fabric_uplink - The module is enhanced to support idempotency. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/253) + - redfish_storage_volume - The module is enhanced to support check mode and + idempotency. (https://github.com/dell/dellemc-openmanage-ansible-modules/issues/245) + release_summary: Added check mode and idempotency support for redfish_storage_volume and idempotency support for ome_smart_fabric_uplink. For ome_diagnostics, added support for debug logs and added supportassist_collection as a choice for the log_type argument to export SupportAssist logs. - release_date: "2022-04-26" + release_date: '2022-04-26' 5.4.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_console_preferences - Issue(224690) - The module does not - display a proper error message when an unsupported value is provided for the - parameters report_row_limit, email_sender_settings, and metric_collection_settings, - and the value is applied on OpenManage Enterprise. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_console_preferences - Issue(224690) - The module does not + display a proper error message when an unsupported value is provided for the + parameters report_row_limit, email_sender_settings, and metric_collection_settings, + and the value is applied on OpenManage Enterprise. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - idrac_server_config_profile - The module is enhanced to support export, import, - and preview the SCP configuration using Redfish and added support for check - mode. - release_summary: - Support for export, import, and preview the Server Configuration + - idrac_server_config_profile - The module is enhanced to support export, import, + and preview the SCP configuration using Redfish and added support for check + mode. + release_summary: Support for export, import, and preview the Server Configuration Profile (SCP) configuration using Redfish and added support for check mode. - release_date: "2022-05-26" + release_date: '2022-05-26' 5.5.0: changes: bugfixes: - - "idrac_server_config_profile - Issue(234817) \u2013 When an XML format is - exported using the SCP, the module breaks while waiting for the job completion." - - ome_application_console_preferences - Issue(224690) - The module does not - display a proper error message when an unsupported value is provided for the - parameters report_row_limit, email_sender_settings, and metric_collection_settings, - and the value is applied on OpenManage Enterprise + - "idrac_server_config_profile - Issue(234817) \u2013 When an XML format is + exported using the SCP, the module breaks while waiting for the job completion." + - ome_application_console_preferences - Issue(224690) - The module does not + display a proper error message when an unsupported value is provided for the + parameters report_row_limit, email_sender_settings, and metric_collection_settings, + and the value is applied on OpenManage Enterprise known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. minor_changes: - - idrac_redfish_storage_controller - This module is updated to use the Job Service - URL instead of Task Service URL for job tracking. - - idrac_server_config_profile - This module is updated to use the Job Service - URL instead of Task Service URL for job tracking. - - redfish_firmware - This module is updated to use the Job Service URL instead - of Task Service URL for job tracking. - release_summary: - Support to generate certificate signing request, import, and + - idrac_redfish_storage_controller - This module is updated to use the Job Service + URL instead of Task Service URL for job tracking. + - idrac_server_config_profile - This module is updated to use the Job Service + URL instead of Task Service URL for job tracking. + - redfish_firmware - This module is updated to use the Job Service URL instead + of Task Service URL for job tracking. + release_summary: Support to generate certificate signing request, import, and export certificates on iDRAC. modules: - - description: Configure certificates for iDRAC. - name: idrac_certificates - namespace: "" - release_date: "2022-06-29" + - description: Configure certificates for iDRAC. + name: idrac_certificates + namespace: '' + release_date: '2022-06-29' 6.0.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - Added collection metadata for creating execution environments. - - Refactored the Markdown (MD) files and content for better readability. - - The share parameters are deprecated from the following modules - idrac_network, - idrac_timezone_ntp, dellemc_configure_idrac_eventing, dellemc_configure_idrac_services, - dellemc_idrac_lc_attributes, dellemc_system_lockdown_mode. - release_summary: - Added collection metadata for creating execution environments, + - Added collection metadata for creating execution environments. + - Refactored the Markdown (MD) files and content for better readability. + - The share parameters are deprecated from the following modules - idrac_network, + idrac_timezone_ntp, dellemc_configure_idrac_eventing, dellemc_configure_idrac_services, + dellemc_idrac_lc_attributes, dellemc_system_lockdown_mode. + release_summary: Added collection metadata for creating execution environments, deprecation of share parameters, and support for configuring iDRAC attributes using idrac_attributes module. modules: - - description: Configure the iDRAC attributes - name: idrac_attributes - namespace: "" - release_date: "2022-07-28" + - description: Configure the iDRAC attributes + name: idrac_attributes + namespace: '' + release_date: '2022-07-28' 6.1.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_smtp - Issue(212310) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_local_access_configuration - Issue(215035) - The module reports - ``Successfully updated the local access setting`` if an unsupported value - is provided for the parameter timeout_limit. However, this value is not actually - applied on OpenManage Enterprise Modular. - - ome_device_local_access_configuration - Issue(217865) - The module does not - display a proper error message if an unsupported value is provided for the - user_defined and lcd_language parameters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_device_quick_deploy - Issue(216352) - The module does not display a proper - error message if an unsupported value is provided for the ipv6_prefix_length - and vlan_id parameters. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_smtp - Issue(212310) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_local_access_configuration - Issue(215035) - The module reports + ``Successfully updated the local access setting`` if an unsupported value + is provided for the parameter timeout_limit. However, this value is not actually + applied on OpenManage Enterprise Modular. + - ome_device_local_access_configuration - Issue(217865) - The module does not + display a proper error message if an unsupported value is provided for the + user_defined and lcd_language parameters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_device_quick_deploy - Issue(216352) - The module does not display a proper + error message if an unsupported value is provided for the ipv6_prefix_length + and vlan_id parameters. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - idrac_boot - Support for configuring the boot settings on iDRAC. - - ome_device_group - The module is enhanced to support the removal of devices - from a static device group. - - ome_devices - Support for performing device-specific operations on OpenManage - Enterprise. + - idrac_boot - Support for configuring the boot settings on iDRAC. + - ome_device_group - The module is enhanced to support the removal of devices + from a static device group. + - ome_devices - Support for performing device-specific operations on OpenManage + Enterprise. minor_changes: - - ome_configuration_compliance_info - The module is enhanced to report single - device compliance information. - release_summary: - Support for device-specific operations on OpenManage Enterprise + - ome_configuration_compliance_info - The module is enhanced to report single + device compliance information. + release_summary: Support for device-specific operations on OpenManage Enterprise and configuring boot settings on iDRAC. modules: - - description: Configure the boot order settings. - name: idrac_boot - namespace: "" - - description: Perform device-specific operations on target devices - name: ome_devices - namespace: "" - release_date: "2022-08-26" + - description: Configure the boot order settings. + name: idrac_boot + namespace: '' + - description: Perform device-specific operations on target devices + name: ome_devices + namespace: '' + release_date: '2022-08-26' 6.2.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - idrac_bios - The module is enhanced to support clear pending BIOS attributes, - reset BIOS to default settings, and configure BIOS attribute using Redfish. - release_summary: - Added clear pending BIOS attributes, reset BIOS to default + - idrac_bios - The module is enhanced to support clear pending BIOS attributes, + reset BIOS to default settings, and configure BIOS attribute using Redfish. + release_summary: Added clear pending BIOS attributes, reset BIOS to default settings, and configure BIOS attribute using Redfish enhancements for idrac_bios. - release_date: "2022-09-28" + release_date: '2022-09-28' 6.3.0: changes: known_issues: - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - idrac_redfish_storage_controller - This module is enhanced to support LockVirtualDisk - operation. - - idrac_virtual_media - This module allows to configure Remote File Share settings. - release_summary: - Support for LockVirtualDisk operation and to configure Remote + - idrac_redfish_storage_controller - This module is enhanced to support LockVirtualDisk + operation. + - idrac_virtual_media - This module allows to configure Remote File Share settings. + release_summary: Support for LockVirtualDisk operation and to configure Remote File Share settings using idrac_virtual_media module. modules: - - description: Configure the virtual media settings. - name: idrac_virtual_media - namespace: "" - release_date: "2022-10-28" + - description: Configure the virtual media settings. + name: idrac_virtual_media + namespace: '' + release_date: '2022-10-28' 7.0.0: changes: known_issues: - - idrac_firmware - Issue(249879) - Firmware update of iDRAC9-based Servers fails - if SOCKS proxy with authentication is used. - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_firmware - Issue(249879) - Firmware update of iDRAC9-based Servers fails + if SOCKS proxy with authentication is used. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - Rebranded from Dell EMC to Dell. - - idrac_firmware - This module is enhanced to support proxy. - - idrac_user_info - This module allows to retrieve iDRAC Local user information - details. - release_summary: - Rebranded from Dell EMC to Dell, enhanced idrac_firmware module + - Rebranded from Dell EMC to Dell. + - idrac_firmware - This module is enhanced to support proxy. + - idrac_user_info - This module allows to retrieve iDRAC Local user information + details. + release_summary: Rebranded from Dell EMC to Dell, enhanced idrac_firmware module to support proxy, and added support to retrieve iDRAC local user details. modules: - - description: Retrieve iDRAC Local user details. - name: idrac_user_info - namespace: "" - release_date: "2022-11-28" + - description: Retrieve iDRAC Local user details. + name: idrac_user_info + namespace: '' + release_date: '2022-11-28' 7.1.0: changes: known_issues: - - idrac_firmware - Issue(249879) - Firmware update of iDRAC9-based Servers fails - if SOCKS proxy with authentication is used. - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_firmware - Issue(249879) - Firmware update of iDRAC9-based Servers fails + if SOCKS proxy with authentication is used. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - Support for IPv6 address for OMSDK dependent iDRAC modules. - - ome_inventory - This plugin allows to create a inventory from the group on - OpenManage Enterprise. - - ome_smart_fabric_info - This module retrieves the list of smart fabrics in - the inventory of OpenManage Enterprise Modular. - - ome_smart_fabric_uplink_info - This module retrieve details of fabric uplink - on OpenManage Enterprise Modular. + - Support for IPv6 address for OMSDK dependent iDRAC modules. + - ome_inventory - This plugin allows to create a inventory from the group on + OpenManage Enterprise. + - ome_smart_fabric_info - This module retrieves the list of smart fabrics in + the inventory of OpenManage Enterprise Modular. + - ome_smart_fabric_uplink_info - This module retrieve details of fabric uplink + on OpenManage Enterprise Modular. minor_changes: - - redfish_firmware - This module supports timeout option. - release_summary: - Support for retrieving smart fabric and smart fabric uplink + - redfish_firmware - This module supports timeout option. + release_summary: Support for retrieving smart fabric and smart fabric uplink information and support for IPv6 address for OMSDK dependent iDRAC modules. modules: - - description: - Retrieves the information of smart fabrics inventoried by OpenManage - Enterprise Modular - name: ome_smart_fabric_info - namespace: "" - - description: Retrieve details of fabric uplink on OpenManage Enterprise Modular. - name: ome_smart_fabric_uplink_info - namespace: "" + - description: Retrieves the information of smart fabrics inventoried by OpenManage + Enterprise Modular + name: ome_smart_fabric_info + namespace: '' + - description: Retrieve details of fabric uplink on OpenManage Enterprise Modular. + name: ome_smart_fabric_uplink_info + namespace: '' plugins: inventory: - - description: Group inventory plugin on OpenManage Enterprise. - name: ome_inventory - namespace: null - release_date: "2022-12-28" + - description: Group inventory plugin on OpenManage Enterprise. + name: ome_inventory + namespace: null + release_date: '2022-12-28' 7.2.0: changes: known_issues: - - idrac_redfish_storage_contoller - Issue(256164) - If incorrect value is provided - for one of the attributes in the provided attribute list for controller configuration, - then this module does not exit with error. - - idrac_user - Issue(192043) The module may error out with the message ``unable - to perform the import or export operation because there are pending attribute - changes or a configuration job is in progress``. Wait for the job to complete - and run the task again. - - ome_application_alerts_syslog - Issue(215374) - The module does not provide - a proper error message if the destination_address is more than 255 characters. - - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- - port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - - ome_device_power_settings - Issue(212679) - The module displays the following - message if the value provided for the parameter ``power_cap`` is not within - the supported range of 0 to 32767, ``Unable to complete the request because - PowerCap does not exist or is not applicable for the resource URI.`` - - ome_inventory - Issue(256257) - All hosts are not retrieved for ``Modular - System`` group and corresponding child groups. - - ome_inventory - Issue(256589) - All hosts are not retrieved for ``Custom Groups`` - group and corresponding child groups. - - ome_inventory - Issue(256593) - All hosts are not retrieved for ``PLUGIN GROUPS`` - group and corresponding child groups. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. + - idrac_redfish_storage_contoller - Issue(256164) - If incorrect value is provided + for one of the attributes in the provided attribute list for controller configuration, + then this module does not exit with error. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_inventory - Issue(256257) - All hosts are not retrieved for ``Modular + System`` group and corresponding child groups. + - ome_inventory - Issue(256589) - All hosts are not retrieved for ``Custom Groups`` + group and corresponding child groups. + - ome_inventory - Issue(256593) - All hosts are not retrieved for ``PLUGIN GROUPS`` + group and corresponding child groups. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. major_changes: - - idrac_redfish_storage_controller - This module is enhanced to configure controller - attributes and online capacity expansion. - - ome_domian_user_groups - This module allows to import the LDAP directory groups. - - ome_inventory - This plugin is enhanced to support inventory retrieval of - System and Plugin Groups of OpenManage Enterprise. - - ome_profile_info - This module allows to retrieve profiles with attributes - on OpenManage Enterprise or OpenManage Enterprise Modular. - - ome_template_network_vlan_info - This module allows to retrieve the network - configuration of a template on OpenManage Enterprise or OpenManage Enterprise - Modular. - release_summary: - Support for retrieving the inventory and host details of all + - idrac_redfish_storage_controller - This module is enhanced to configure controller + attributes and online capacity expansion. + - ome_domian_user_groups - This module allows to import the LDAP directory groups. + - ome_inventory - This plugin is enhanced to support inventory retrieval of + System and Plugin Groups of OpenManage Enterprise. + - ome_profile_info - This module allows to retrieve profiles with attributes + on OpenManage Enterprise or OpenManage Enterprise Modular. + - ome_template_network_vlan_info - This module allows to retrieve the network + configuration of a template on OpenManage Enterprise or OpenManage Enterprise + Modular. + release_summary: Support for retrieving the inventory and host details of all child groups using parent groups, retrieving inventory of System and Plugin Groups, retrieving profiles with attributes, retrieving network configuration of a template, configuring controller attributes, configuring online capacity expansion, and importing the LDAP directory. modules: - - description: Retrieve profiles with attribute details - name: ome_profile_info - namespace: "" - - description: Retrieves network configuration of template. - name: ome_template_network_vlan_info - namespace: "" - release_date: "2023-01-30" + - description: Retrieve profiles with attribute details + name: ome_profile_info + namespace: '' + - description: Retrieves network configuration of template. + name: ome_template_network_vlan_info + namespace: '' + release_date: '2023-01-30' 7.3.0: + changes: + known_issues: + - idrac_redfish_storage_contoller - Issue(256164) - If incorrect value is provided + for one of the attributes in the provided attribute list for controller configuration, + then this module does not exit with error. + - idrac_user - Issue(192043) The module may error out with the message ``unable + to perform the import or export operation because there are pending attribute + changes or a configuration job is in progress``. Wait for the job to complete + and run the task again. + - ome_application_alerts_syslog - Issue(215374) - The module does not provide + a proper error message if the destination_address is more than 255 characters. + - ome_device_network_services - Issue(212681) - The module does not provide + a proper error message if unsupported values are provided for the parameters- + port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. + - ome_device_power_settings - Issue(212679) - The module displays the following + message if the value provided for the parameter ``power_cap`` is not within + the supported range of 0 to 32767, ``Unable to complete the request because + PowerCap does not exist or is not applicable for the resource URI.`` + - ome_inventory - Issue(256257) - All hosts are not retrieved for ``Modular + System`` group and corresponding child groups. + - ome_inventory - Issue(256589) - All hosts are not retrieved for ``Custom Groups`` + group and corresponding child groups. + - ome_inventory - Issue(256593) - All hosts are not retrieved for ``PLUGIN GROUPS`` + group and corresponding child groups. + - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation + of multiple uplinks of the same name even though it is supported by OpenManage + Enterprise Modular. If an uplink is created using the same name as an existing + uplink, the existing uplink is modified. + major_changes: + - idrac_server_config_profile - This module is enhanced to support proxy settings, + import buffer, include in export, and ignore certificate warning. + release_summary: Support for iDRAC export Server Configuration Profile role + and proxy settings, import buffer, include in export, and ignore certificate + warning. + objects: + role: + - description: Role to export iDRAC Server Configuration Profile (SCP). + name: idrac_export_server_config_profile + namespace: null + release_date: '2023-02-28' + 7.4.0: changes: known_issues: - idrac_redfish_storage_contoller - Issue(256164) - If incorrect value is provided for one of the attributes in the provided attribute list for controller configuration, then this module does not exit with error. - - idrac_user - Issue(192043) The module may error out with the message ``unable + - idrac_user - Issue(192043) The module may error out with the message ``Unable to perform the import or export operation because there are pending attribute changes or a configuration job is in progress``. Wait for the job to complete and run the task again. - ome_application_alerts_syslog - Issue(215374) - The module does not provide a proper error message if the destination_address is more than 255 characters. - ome_device_network_services - Issue(212681) - The module does not provide - a proper error message if unsupported values are provided for the parameters- + a proper error message if unsupported values are provided for the following parameters- port_number, community_name, max_sessions, max_auth_retries, and idle_timeout. - ome_device_power_settings - Issue(212679) - The module displays the following message if the value provided for the parameter ``power_cap`` is not within the supported range of 0 to 32767, ``Unable to complete the request because PowerCap does not exist or is not applicable for the resource URI.`` - - ome_inventory - Issue(256257) - All hosts are not retrieved for ``Modular - System`` group and corresponding child groups. - - ome_inventory - Issue(256589) - All hosts are not retrieved for ``Custom Groups`` - group and corresponding child groups. - - ome_inventory - Issue(256593) - All hosts are not retrieved for ``PLUGIN GROUPS`` - group and corresponding child groups. - - ome_smart_fabric_uplink - Issue(186024) - The module does not allow the creation - of multiple uplinks of the same name even though it is supported by OpenManage - Enterprise Modular. If an uplink is created using the same name as an existing - uplink, the existing uplink is modified. - major_changes: - - idrac_server_config_profile - This module is enhanced to support proxy settings, - import buffer, include in export, and ignore certificate warning. - release_summary: - Support for iDRAC export Server Configuration Profile role - and proxy settings, import buffer, include in export, and ignore - certificate warning. + - ome_smart_fabric_uplink - Issue(186024) - Despite the module supported by OpenManage Enterprise Modular, + it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the + same name as an existing uplink, the existing uplink is modified. + - idrac_os_deployment- Issue(260496) - OS installation will support only NFS and CIFS + share to store the custom ISO in the destination_path, HTTP/HTTPS/FTP not supported + release_summary: | + - Role to support the Import server configuration profile, Manage iDRAC power states, Manage iDRAC certificate, + Gather facts from iDRAC and Deploy operating system is added. + - Plugin OME inventory is enhanced to support the environment variables for the input parameters. objects: role: - - description: Role to export iDRAC Server Configuration Profile (SCP). - name: idrac_export_server_config_profile - namespace: null - release_date: "2023-02-28" + - description: Role to manage the iDRAC certificates - generate CSR, import/export + certificates, and reset configuration - for PowerEdge servers. + name: idrac_certificate + namespace: null + - description: Role to gather facts from the iDRAC Server. + name: idrac_gather_facts + namespace: null + - description: Role to import iDRAC Server Configuration Profile (SCP). + name: idrac_import_server_config_profile + namespace: null + - description: Role to manage the different power states of the specified device. + name: idrac_server_powerstate + namespace: null + - description: Role to deploy specified operating system and version on the servers. + name: idrac_os_deployment + namespace: null + release_date: '2023-03-30' diff --git a/galaxy.yml b/galaxy.yml index 30b414af5..0b7d2ebd8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: dellemc name: openmanage -version: 7.3.0 +version: 7.4.0 readme: README.md authors: - Jagadeesh N V diff --git a/plugins/inventory/ome_inventory.py b/plugins/inventory/ome_inventory.py index 3d64c5271..08481ab05 100644 --- a/plugins/inventory/ome_inventory.py +++ b/plugins/inventory/ome_inventory.py @@ -2,7 +2,7 @@ # # Dell OpenManage Ansible Modules -# Version 7.2.0 +# Version 7.4.0 # Copyright (C) 2022-2023 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) @@ -18,9 +18,52 @@ short_description: Group inventory plugin on OpenManage Enterprise. description: This plugin allows to retrieve inventory hosts from groups on OpenManage Enterprise. version_added: "7.1.0" -extends_documentation_fragment: - - dellemc.openmanage.ome_auth_options options: + hostname: + description: + - OpenManage Enterprise or OpenManage Enterprise Modular IP address or hostname. + - If the value is not specified in the task, the value of environment variable C(OME_HOSTNAME) will be used instead. + env: + - name: OME_HOSTNAME + type: str + required: True + username: + description: + - OpenManage Enterprise or OpenManage Enterprise Modular username. + - If the value is not specified in the task, the value of environment variable C(OME_USERNAME) will be used instead. + env: + - name: OME_USERNAME + type: str + required: True + password: + description: + - OpenManage Enterprise or OpenManage Enterprise Modular password. + - If the value is not specified in the task, the value of environment variable C(OME_PASSWORD) will be used instead. + env: + - name: OME_PASSWORD + type: str + required: True + port: + description: + - OpenManage Enterprise or OpenManage Enterprise Modular HTTPS port. + - If the value is not specified in the task, the value of environment variable C(OME_PORT) will be used instead. + type: int + 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 C(5.0.0), the 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 + timeout: + description: The socket level timeout in seconds. + type: int + default: 30 ome_group_name: description: Group name. type: str @@ -96,12 +139,12 @@ def __init__(self): self.config = None def _get_connection_resp(self): - port = self.config.get("port") if "port" in self.config else 443 - validate_certs = self.config.get("validate_certs") if "validate_certs" in self.config else False - module_params = {"hostname": self.config.get("hostname"), "username": self.config.get("username"), - "password": self.config.get("password"), "port": port, "validate_certs": validate_certs} + port = self.get_option("port") if "port" in self.config else 443 + validate_certs = self.get_option("validate_certs") if "validate_certs" in self.config else False + module_params = {"hostname": self.get_option("hostname"), "username": self.get_option("username"), + "password": self.get_option("password"), "port": port, "validate_certs": validate_certs} if "ca_path" in self.config: - module_params.update({"ca_path": self.config.get("ca_path")}) + module_params.update({"ca_path": self.get_option("ca_path")}) with RestOME(module_params, req_session=False) as ome: resp = ome.invoke_request("GET", GROUP_API) return resp.json_data @@ -111,14 +154,14 @@ def _set_host_vars(self, host): self.inventory.set_variable(host, "baseuri", host) self.inventory.set_variable(host, "hostname", host) if "host_vars" in self.config: - host_vars = self.config.get("host_vars") + host_vars = self.get_option("host_vars") for key, val in dict(host_vars).items(): self.inventory.set_variable(host, key, val) def _set_group_vars(self, group): self.inventory.add_group(group) if "group_vars" in self.config: - group_vars = self.config.get("group_vars") + group_vars = self.get_option("group_vars") if group in dict(group_vars): for key, val in dict(dict(group_vars)[group]).items(): self.inventory.set_variable(group, key, val) @@ -126,12 +169,12 @@ def _set_group_vars(self, group): def _get_all_devices(self, device_uri): device_host = [] device_host_uri = device_uri.strip("/api/") - port = self.config.get("port") if "port" in self.config else 443 - validate_certs = self.config.get("validate_certs") if "validate_certs" in self.config else False - module_params = {"hostname": self.config.get("hostname"), "username": self.config.get("username"), - "password": self.config.get("password"), "port": port, "validate_certs": validate_certs} + port = self.get_option("port") if "port" in self.config else 443 + validate_certs = self.get_option("validate_certs") if "validate_certs" in self.config else False + module_params = {"hostname": self.get_option("hostname"), "username": self.get_option("username"), + "password": self.get_option("password"), "port": port, "validate_certs": validate_certs} if "ca_path" in self.config: - module_params.update({"ca_path": self.config.get("ca_path")}) + module_params.update({"ca_path": self.get_option("ca_path")}) with RestOME(module_params, req_session=False) as ome: device_resp = ome.invoke_request("GET", device_host_uri) device_data = device_resp.json_data.get("value") @@ -150,12 +193,12 @@ def _get_all_devices(self, device_uri): return device_host def _set_child_group(self, group_data): - port = self.config.get("port") if "port" in self.config else 443 - validate_certs = self.config.get("validate_certs") if "validate_certs" in self.config else False - module_params = {"hostname": self.config.get("hostname"), "username": self.config.get("username"), - "password": self.config.get("password"), "port": port, "validate_certs": validate_certs} + port = self.get_option("port") if "port" in self.config else 443 + validate_certs = self.get_option("validate_certs") if "validate_certs" in self.config else False + module_params = {"hostname": self.get_option("hostname"), "username": self.get_option("username"), + "password": self.get_option("password"), "port": port, "validate_certs": validate_certs} if "ca_path" in self.config: - module_params.update({"ca_path": self.config.get("ca_path")}) + module_params.update({"ca_path": self.get_option("ca_path")}) with RestOME(module_params, req_session=False) as ome: for gdata in group_data: group_name = gdata["Name"] @@ -177,7 +220,7 @@ def _add_group_data(self, group_data): group_data.remove(gp) for gdata in group_data: self._set_group_vars(gdata["Name"]) - device_ip = self._get_all_devices(gdata["Devices@odata.navigationLink"]) + device_ip = self._get_all_devices(gdata["AllLeafDevices@odata.navigationLink"]) for hst in device_ip: self.inventory.add_host(host=hst, group=gdata["Name"]) self._set_host_vars(hst) @@ -185,7 +228,7 @@ def _add_group_data(self, group_data): def _populate(self, inventory_data): group_data = inventory_data.get("value") - group_name = str(self.config.get("ome_group_name")) if "ome_group_name" in self.config else None + group_name = str(self.get_option("ome_group_name")) if "ome_group_name" in self.config else None if group_name is not None: group_data = list(filter(lambda d: d.get("Name").lower() in [group_name.lower()], group_data)) elif group_name is None: diff --git a/plugins/module_utils/dellemc_idrac.py b/plugins/module_utils/dellemc_idrac.py index 66d7089ec..a8fd0e09f 100644 --- a/plugins/module_utils/dellemc_idrac.py +++ b/plugins/module_utils/dellemc_idrac.py @@ -33,7 +33,6 @@ try: from omsdk.sdkinfra import sdkinfra from omsdk.sdkcreds import UserCredentials - from omsdk.sdkfile import FileOnShare, file_share_manager from omsdk.sdkprotopref import ProtoPreference, ProtocolEnum from omsdk.http.sdkwsmanbase import WsManOptions HAS_OMSDK = True diff --git a/plugins/module_utils/idrac_redfish.py b/plugins/module_utils/idrac_redfish.py index 771734996..c19632a71 100644 --- a/plugins/module_utils/idrac_redfish.py +++ b/plugins/module_utils/idrac_redfish.py @@ -216,7 +216,7 @@ def get_server_generation(self): This method fetches the connected server generation. :return: 14, 4.11.11.11 """ - model, firmware_version = None, None + firmware_version = None response = self.invoke_request(MANAGER_URI, 'GET') if response.status_code == 200: generation = int(re.search(r"\d+(?=G)", response.json_data["Model"]).group()) diff --git a/plugins/module_utils/utils.py b/plugins/module_utils/utils.py index d0da26e57..b33d209fe 100644 --- a/plugins/module_utils/utils.py +++ b/plugins/module_utils/utils.py @@ -45,7 +45,7 @@ import time -from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError +from ansible.module_utils.six.moves.urllib.error import HTTPError def strip_substr_dict(odata_dict, chkstr='@odata.', case_sensitive=False): @@ -265,8 +265,8 @@ def reset_idrac(idrac_restobj, wait_time_sec=300, res_id=MANAGER_ID, interval=30 track_failed = True reset_msg = "iDRAC reset triggered successfully." try: - resp = idrac_restobj.invoke_request(IDRAC_RESET_URI.format(res_id=res_id), 'POST', - data={"ResetType": "GracefulRestart"}) + idrac_restobj.invoke_request(IDRAC_RESET_URI.format(res_id=res_id), 'POST', + data={"ResetType": "GracefulRestart"}) if wait_time_sec: track_failed, reset_msg = wait_after_idrac_reset(idrac_restobj, wait_time_sec, interval) reset = True diff --git a/plugins/modules/dellemc_configure_idrac_eventing.py b/plugins/modules/dellemc_configure_idrac_eventing.py index 8a68c5042..df1b8724c 100644 --- a/plugins/modules/dellemc_configure_idrac_eventing.py +++ b/plugins/modules/dellemc_configure_idrac_eventing.py @@ -195,7 +195,6 @@ AlertEnable_IPMILanTypes, SMTPAuthentication_RemoteHostsTypes) from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/dellemc_configure_idrac_services.py b/plugins/modules/dellemc_configure_idrac_services.py index bb4fb06e3..56facf9c8 100644 --- a/plugins/modules/dellemc_configure_idrac_services.py +++ b/plugins/modules/dellemc_configure_idrac_services.py @@ -235,7 +235,6 @@ AgentEnable_SNMPTypes, SNMPProtocol_SNMPTypes) from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/dellemc_get_firmware_inventory.py b/plugins/modules/dellemc_get_firmware_inventory.py index 83bbe98f8..d15193e71 100644 --- a/plugins/modules/dellemc_get_firmware_inventory.py +++ b/plugins/modules/dellemc_get_firmware_inventory.py @@ -89,13 +89,6 @@ import traceback from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params from ansible.module_utils.basic import AnsibleModule -try: - from omsdk.sdkfile import LocalFile - from omsdk.catalog.sdkupdatemgr import UpdateManager - from omdrivers.helpers.iDRAC.UpdateHelper import UpdateHelper - HAS_OMSDK = True -except ImportError: - HAS_OMSDK = False def run_get_firmware_inventory(idrac, module): diff --git a/plugins/modules/dellemc_idrac_lc_attributes.py b/plugins/modules/dellemc_idrac_lc_attributes.py index d7c7e6189..659c08381 100644 --- a/plugins/modules/dellemc_idrac_lc_attributes.py +++ b/plugins/modules/dellemc_idrac_lc_attributes.py @@ -142,7 +142,6 @@ try: from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/dellemc_system_lockdown_mode.py b/plugins/modules/dellemc_system_lockdown_mode.py index 33a215cbc..82b8d5ace 100644 --- a/plugins/modules/dellemc_system_lockdown_mode.py +++ b/plugins/modules/dellemc_system_lockdown_mode.py @@ -145,7 +145,6 @@ from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError try: from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/idrac_attributes.py b/plugins/modules/idrac_attributes.py index e29391c44..47b9d294b 100644 --- a/plugins/modules/idrac_attributes.py +++ b/plugins/modules/idrac_attributes.py @@ -262,7 +262,7 @@ import re from ssl import SSLError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI, idrac_auth_params from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import get_manager_res_id from ansible.module_utils.basic import AnsibleModule @@ -510,7 +510,7 @@ def main(): res_id = get_manager_res_id(idrac) diff, uri_dict, idrac_response_attr, system_response_attr, lc_response_attr = fetch_idrac_uri_attr(idrac, module, res_id) process_check_mode(module, diff) - resp = update_idrac_attributes(idrac, module, uri_dict, idrac_response_attr, system_response_attr, lc_response_attr) + update_idrac_attributes(idrac, module, uri_dict, idrac_response_attr, system_response_attr, lc_response_attr) module.exit_json(msg=SUCCESS_MSG, changed=True) except HTTPError as err: module.fail_json(msg=str(err), error_info=json.load(err)) diff --git a/plugins/modules/idrac_bios.py b/plugins/modules/idrac_bios.py index 52ea0ebf2..67eca3621 100644 --- a/plugins/modules/idrac_bios.py +++ b/plugins/modules/idrac_bios.py @@ -562,7 +562,7 @@ def track_log_entry(redfish_obj): else: # msg = "{0}{1}".format(BIOS_RESET_TRIGGERED, "LOOPOVER") msg = BIOS_RESET_TRIGGERED - except Exception as ex: + except Exception: # msg = "{0}{1}".format(BIOS_RESET_TRIGGERED, str(ex)) msg = BIOS_RESET_TRIGGERED return msg @@ -574,7 +574,7 @@ def reset_bios(module, redfish_obj): module.exit_json(status_msg=BIOS_RESET_PENDING, failed=True) if module.check_mode: module.exit_json(status_msg=CHANGES_MSG, changed=True) - resp = redfish_obj.invoke_request(RESET_BIOS_DEFAULT, "POST", data="{}", dump=True) + redfish_obj.invoke_request(RESET_BIOS_DEFAULT, "POST", data="{}", dump=True) reset_success = reset_host(module, redfish_obj) if not reset_success: module.exit_json(failed=True, status_msg="{0} {1}".format(RESET_TRIGGERRED, HOST_RESTART_FAILED)) @@ -599,7 +599,7 @@ def clear_pending_bios(module, redfish_obj): module.exit_json(status_msg=SUCCESS_CLEAR, changed=True) if module.check_mode: module.exit_json(status_msg=CHANGES_MSG, changed=True) - resp = redfish_obj.invoke_request(CLEAR_PENDING_URI, "POST", data="{}", dump=False) + redfish_obj.invoke_request(CLEAR_PENDING_URI, "POST", data="{}", dump=False) module.exit_json(status_msg=SUCCESS_CLEAR, changed=True) @@ -699,7 +699,7 @@ def apply_attributes(module, redfish_obj, pending, rf_settings): payload["@Redfish.SettingsApplyTime"] = rf_set resp = redfish_obj.invoke_request(BIOS_SETTINGS, "PATCH", data=payload) if rf_set: - tmp_resp = redfish_obj.invoke_request(resp.headers["Location"], "GET") + redfish_obj.invoke_request(resp.headers["Location"], "GET") job_id = resp.headers["Location"].split("/")[-1] else: if aplytm == "Immediate": diff --git a/plugins/modules/idrac_boot.py b/plugins/modules/idrac_boot.py index ad563c5ce..276ff6f31 100644 --- a/plugins/modules/idrac_boot.py +++ b/plugins/modules/idrac_boot.py @@ -413,7 +413,7 @@ def apply_boot_settings(module, idrac, payload, res_id): def configure_boot_settings(module, idrac, res_id): - job_resp, diff_change, payload = {}, [], {"Boot": {}} + job_resp, payload = {}, {"Boot": {}} boot_order = module.params.get("boot_order") override_mode = module.params.get("boot_source_override_mode") override_enabled = module.params.get("boot_source_override_enabled") @@ -457,7 +457,7 @@ def configure_boot_settings(module, idrac, res_id): def configure_idrac_boot(module, idrac, res_id): boot_options = module.params.get("boot_options") - inv_boot_options, diff_change, payload, job_resp, boot_attr = [], [], {}, {}, {} + inv_boot_options, diff_change, payload, job_resp = [], [], {}, {} if boot_options is not None: boot_option_data = get_existing_boot_options(idrac, res_id) for each in boot_options: @@ -552,7 +552,7 @@ def main(): if err.code == 401: module.fail_json(msg=AUTH_ERROR_MSG.format(module.params["idrac_ip"])) module.fail_json(msg=str(err), error_info=json.load(err)) - except URLError as err: + except URLError: module.exit_json(msg=AUTH_ERROR_MSG.format(module.params["idrac_ip"]), unreachable=True) except (ImportError, ValueError, RuntimeError, SSLValidationError, ConnectionError, KeyError, TypeError, IndexError) as e: diff --git a/plugins/modules/idrac_certificates.py b/plugins/modules/idrac_certificates.py index defdc9fd2..06a08a78b 100644 --- a/plugins/modules/idrac_certificates.py +++ b/plugins/modules/idrac_certificates.py @@ -365,7 +365,7 @@ def get_actions_map(idrac, idrac_service_uri): resp = idrac.invoke_request(idrac_service_uri, 'GET') srvc_data = resp.json_data actions = dict((k, v.get('target')) for k, v in srvc_data.get('Actions').items()) - except Exception as exc: + except Exception: actions = idrac_service_actions return actions diff --git a/plugins/modules/idrac_firmware.py b/plugins/modules/idrac_firmware.py index bf101a43a..e2383a5be 100644 --- a/plugins/modules/idrac_firmware.py +++ b/plugins/modules/idrac_firmware.py @@ -233,19 +233,17 @@ import os import json import time -import socket from ssl import SSLError from xml.etree import ElementTree as ET from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six.moves.urllib.parse import urlparse -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError try: from omsdk.sdkcreds import UserCredentials from omsdk.sdkfile import FileOnShare - from omsdk.http.sdkwsmanbase import WsManProtocolBase HAS_OMSDK = True except ImportError: HAS_OMSDK = False @@ -444,7 +442,7 @@ def get_error_syslog(idrac, curr_time, uri): else: msg = "No Error log found." error_log_found = False - except Exception as ex: + except Exception: msg = "No Error log found." error_log_found = False return error_log_found, msg diff --git a/plugins/modules/idrac_firmware_info.py b/plugins/modules/idrac_firmware_info.py index fde6f11c8..cee6b6c05 100644 --- a/plugins/modules/idrac_firmware_info.py +++ b/plugins/modules/idrac_firmware_info.py @@ -110,13 +110,6 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError -try: - from omsdk.sdkfile import LocalFile - from omsdk.catalog.sdkupdatemgr import UpdateManager - from omdrivers.helpers.iDRAC.UpdateHelper import UpdateHelper - HAS_OMSDK = True -except ImportError: - HAS_OMSDK = False # Main diff --git a/plugins/modules/idrac_lifecycle_controller_job_status_info.py b/plugins/modules/idrac_lifecycle_controller_job_status_info.py index 142a7e211..78b63e9b2 100644 --- a/plugins/modules/idrac_lifecycle_controller_job_status_info.py +++ b/plugins/modules/idrac_lifecycle_controller_job_status_info.py @@ -114,7 +114,7 @@ def main(): try: with iDRACConnection(module.params) as idrac: - job_id, msg, failed = module.params.get('job_id'), {}, False + job_id, msg = module.params.get('job_id'), {} msg = idrac.job_mgr.get_job_status(job_id) if msg.get('Status') == "Found Fault": module.fail_json(msg="Job ID is invalid.") diff --git a/plugins/modules/idrac_network.py b/plugins/modules/idrac_network.py index f3f854675..f857c1fb6 100644 --- a/plugins/modules/idrac_network.py +++ b/plugins/modules/idrac_network.py @@ -247,10 +247,8 @@ Selection_NICTypes, Failover_NICTypes, AutoDetect_NICTypes, Autoneg_NICTypes, Speed_NICTypes, Duplex_NICTypes, DHCPEnable_IPv4Types, - DNSFromDHCP_IPv4Types, Enable_IPv4Types, - DNSFromDHCP_IPv4StaticTypes) + Enable_IPv4Types, DNSFromDHCP_IPv4StaticTypes) from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/idrac_redfish_storage_controller.py b/plugins/modules/idrac_redfish_storage_controller.py index f9f1acb23..015de4662 100644 --- a/plugins/modules/idrac_redfish_storage_controller.py +++ b/plugins/modules/idrac_redfish_storage_controller.py @@ -753,7 +753,7 @@ def target_identify_pattern(module, redfish_obj): def lock_virtual_disk(module, redfish_obj): - volume, command = module.params.get("volume_id"), module.params["command"] + volume = module.params.get("volume_id") resp, job_uri, job_id = None, None, None controller_id = volume[0].split(":")[-1] check_id_exists(module, redfish_obj, "controller_id", controller_id, CONTROLLER_URI) @@ -803,7 +803,7 @@ def online_capacity_expansion(module, redfish_obj): volume_resp = redfish_obj.invoke_request("GET", volume_uri.format(system_id=SYSTEM_ID, controller_id=controller_id, volume_id=volume_id[0])) - except HTTPError as err: + except HTTPError: module.exit_json(msg=VD_ERROR_MSG.format(volume_id[0]), failed=True) try: diff --git a/plugins/modules/idrac_server_config_profile.py b/plugins/modules/idrac_server_config_profile.py index f60707682..00f621177 100644 --- a/plugins/modules/idrac_server_config_profile.py +++ b/plugins/modules/idrac_server_config_profile.py @@ -3,7 +3,7 @@ # # Dell OpenManage Ansible Modules -# Version 7.3.0 +# Version 7.4.0 # Copyright (C) 2019-2023 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) @@ -513,7 +513,6 @@ import os import json -import re import copy from datetime import datetime from os.path import exists diff --git a/plugins/modules/idrac_timezone_ntp.py b/plugins/modules/idrac_timezone_ntp.py index ba064fcbc..3661f2650 100644 --- a/plugins/modules/idrac_timezone_ntp.py +++ b/plugins/modules/idrac_timezone_ntp.py @@ -159,7 +159,6 @@ try: from omdrivers.enums.iDRAC.iDRAC import NTPEnable_NTPConfigGroupTypes from omsdk.sdkfile import file_share_manager - from omsdk.sdkcreds import UserCredentials except ImportError: pass diff --git a/plugins/modules/idrac_virtual_media.py b/plugins/modules/idrac_virtual_media.py index ac22541eb..682e4620c 100644 --- a/plugins/modules/idrac_virtual_media.py +++ b/plugins/modules/idrac_virtual_media.py @@ -313,7 +313,7 @@ def _validate_params(module, vr_members, rd_version): def virtual_media_operation(idrac, module, payload, vr_id): - err_payload, inserted = [], [] + err_payload = [] force = module.params["force"] for i in payload: diff --git a/plugins/modules/ome_active_directory.py b/plugins/modules/ome_active_directory.py index bbc06477b..85a8325ea 100644 --- a/plugins/modules/ome_active_directory.py +++ b/plugins/modules/ome_active_directory.py @@ -397,7 +397,7 @@ def delete_ad(module, rest_obj, ad): ad = rest_obj.strip_substr_dict(ad) if module.check_mode: module.exit_json(msg=CHANGES_FOUND, active_directory=ad, changed=True) - resp = rest_obj.invoke_request('POST', DELETE_AD, data={"AccountProviderIds": [int(ad['Id'])]}) + rest_obj.invoke_request('POST', DELETE_AD, data={"AccountProviderIds": [int(ad['Id'])]}) module.exit_json(msg=DELETE_SUCCESS, active_directory=ad, changed=True) diff --git a/plugins/modules/ome_application_network_address.py b/plugins/modules/ome_application_network_address.py index a730ba501..ab8814a42 100644 --- a/plugins/modules/ome_application_network_address.py +++ b/plugins/modules/ome_application_network_address.py @@ -428,7 +428,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError IP_CONFIG = "ApplicationService/Network/AddressConfiguration" @@ -598,7 +598,7 @@ def get_network_config_data(rest_obj, module): return int_adp, "POST", POST_IP_CONFIG else: return pri_adp, "POST", POST_IP_CONFIG - except HTTPError as err: + except HTTPError: pass except Exception as err: raise err diff --git a/plugins/modules/ome_application_network_proxy.py b/plugins/modules/ome_application_network_proxy.py index ace639fc9..0ca58de09 100644 --- a/plugins/modules/ome_application_network_proxy.py +++ b/plugins/modules/ome_application_network_proxy.py @@ -147,7 +147,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError PROXY_CONFIG = "ApplicationService/Network/ProxyConfiguration" diff --git a/plugins/modules/ome_application_network_time.py b/plugins/modules/ome_application_network_time.py index 808280cb1..baf533c0a 100644 --- a/plugins/modules/ome_application_network_time.py +++ b/plugins/modules/ome_application_network_time.py @@ -141,7 +141,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError TIME_CONFIG = "ApplicationService/Network/TimeConfiguration" diff --git a/plugins/modules/ome_device_group.py b/plugins/modules/ome_device_group.py index 56c1def60..6ea1f25f3 100644 --- a/plugins/modules/ome_device_group.py +++ b/plugins/modules/ome_device_group.py @@ -281,7 +281,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError try: from netaddr import IPAddress, IPNetwork, IPRange @@ -511,7 +511,7 @@ def main(): group_id=group_id, changed=True) else: current_device_list = get_current_member_of_group(rest_obj, group_id) - resp = remove_member_from_group(module, rest_obj, group_id, device_id, current_device_list) + remove_member_from_group(module, rest_obj, group_id, device_id, current_device_list) module.exit_json(msg="Successfully removed member(s) from the device group.", changed=True) except HTTPError as err: module.fail_json(msg=str(err), error_info=json.load(err)) diff --git a/plugins/modules/ome_devices.py b/plugins/modules/ome_devices.py index 954395280..3514a9351 100644 --- a/plugins/modules/ome_devices.py +++ b/plugins/modules/ome_devices.py @@ -233,8 +233,7 @@ from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import \ - get_rest_items, strip_substr_dict, job_tracking, apply_diff_key +from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import strip_substr_dict, job_tracking from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import CHANGES_MSG, NO_CHANGES_MSG DEVICE_URI = "DeviceService/Devices" diff --git a/plugins/modules/ome_discovery.py b/plugins/modules/ome_discovery.py index 117e0307b..ea74a0f8b 100644 --- a/plugins/modules/ome_discovery.py +++ b/plugins/modules/ome_discovery.py @@ -625,7 +625,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.common.dict_transformations import snake_dict_to_camel_dict diff --git a/plugins/modules/ome_firmware.py b/plugins/modules/ome_firmware.py index d1474f33a..1a6d38a01 100644 --- a/plugins/modules/ome_firmware.py +++ b/plugins/modules/ome_firmware.py @@ -327,7 +327,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError diff --git a/plugins/modules/ome_firmware_baseline_info.py b/plugins/modules/ome_firmware_baseline_info.py index 4c142697e..261d67030 100644 --- a/plugins/modules/ome_firmware_baseline_info.py +++ b/plugins/modules/ome_firmware_baseline_info.py @@ -104,7 +104,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError def get_specific_baseline(module, baseline_name, resp_data): diff --git a/plugins/modules/ome_identity_pool.py b/plugins/modules/ome_identity_pool.py index 6b3d75aeb..47e52be9f 100644 --- a/plugins/modules/ome_identity_pool.py +++ b/plugins/modules/ome_identity_pool.py @@ -265,7 +265,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError IDENTITY_URI = "IdentityPoolService/IdentityPools" diff --git a/plugins/modules/ome_network_vlan.py b/plugins/modules/ome_network_vlan.py index 6f669d4c5..393f44a71 100644 --- a/plugins/modules/ome_network_vlan.py +++ b/plugins/modules/ome_network_vlan.py @@ -185,7 +185,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError VLAN_CONFIG = "NetworkConfigurationService/Networks" @@ -254,7 +254,7 @@ def create_vlan(module, rest_obj, vlans): def delete_vlan(module, rest_obj, vlan_id): if module.check_mode: module.exit_json(changed=True, msg=CHECK_MODE_MSG) - resp = rest_obj.invoke_request("DELETE", VLAN_ID_CONFIG.format(Id=vlan_id)) + rest_obj.invoke_request("DELETE", VLAN_ID_CONFIG.format(Id=vlan_id)) module.exit_json(msg="Successfully deleted the VLAN.", changed=True) diff --git a/plugins/modules/ome_profile.py b/plugins/modules/ome_profile.py index 7c57d1401..79668a7a0 100644 --- a/plugins/modules/ome_profile.py +++ b/plugins/modules/ome_profile.py @@ -600,7 +600,7 @@ def assign_profile(module, rest_obj): ad_opts = mparam.get("attributes") for opt in ad_opts_list: if ad_opts and ad_opts.get(opt): - diff = attributes_check(module, rest_obj, ad_opts, prof['Id']) + attributes_check(module, rest_obj, ad_opts, prof['Id']) payload[opt] = ad_opts.get(opt) if module.check_mode: module.exit_json(msg=CHANGES_MSG, changed=True) @@ -710,7 +710,7 @@ def modify_profile(module, rest_obj): if diff: if module.check_mode: module.exit_json(msg=CHANGES_MSG, changed=True) - resp = rest_obj.invoke_request('PUT', PROFILE_VIEW + "({0})".format(payload['Id']), data=payload) + rest_obj.invoke_request('PUT', PROFILE_VIEW + "({0})".format(payload['Id']), data=payload) module.exit_json(msg="Successfully modified the profile.", changed=True) module.exit_json(msg=NO_CHANGES_MSG) @@ -724,7 +724,7 @@ def delete_profile(module, rest_obj): module.fail_json(msg="Profile has to be in an unassigned state for it to be deleted.") if module.check_mode: module.exit_json(msg=CHANGES_MSG, changed=True) - resp = rest_obj.invoke_request('DELETE', PROFILE_VIEW + "({0})".format(prof['Id'])) + rest_obj.invoke_request('DELETE', PROFILE_VIEW + "({0})".format(prof['Id'])) module.exit_json(msg="Successfully deleted the profile.", changed=True) else: module.exit_json(msg=PROFILE_NOT_FOUND.format(name=mparam.get('name'))) @@ -732,7 +732,7 @@ def delete_profile(module, rest_obj): payload = mparam.get('filters') if module.check_mode: module.exit_json(msg=CHANGES_MSG, changed=True) - resp = rest_obj.invoke_request('POST', PROFILE_ACTION.format(action='Delete'), data=payload) + rest_obj.invoke_request('POST', PROFILE_ACTION.format(action='Delete'), data=payload) module.exit_json(msg="Successfully completed the delete operation.", changed=True) diff --git a/plugins/modules/ome_template_identity_pool.py b/plugins/modules/ome_template_identity_pool.py index 8ae70232d..88a09ae95 100644 --- a/plugins/modules/ome_template_identity_pool.py +++ b/plugins/modules/ome_template_identity_pool.py @@ -93,7 +93,7 @@ import json from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ssl import SSLError diff --git a/plugins/modules/ome_template_network_vlan.py b/plugins/modules/ome_template_network_vlan.py index ef1e16bbf..c9d0bd97d 100644 --- a/plugins/modules/ome_template_network_vlan.py +++ b/plugins/modules/ome_template_network_vlan.py @@ -194,7 +194,7 @@ from ssl import SSLError from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME, ome_auth_params -from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError NETWORK_HIERARCHY_VIEW = 4 # For Network hierarchy View in a Template diff --git a/plugins/modules/redfish_powerstate.py b/plugins/modules/redfish_powerstate.py index 1164f39c4..b57863eb6 100644 --- a/plugins/modules/redfish_powerstate.py +++ b/plugins/modules/redfish_powerstate.py @@ -121,7 +121,7 @@ from ansible_collections.dellemc.openmanage.plugins.module_utils.redfish import Redfish, redfish_auth_params from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import ConnectionError powerstate_map = {} diff --git a/roles/idrac_certificate/.yamllint b/roles/idrac_certificate/.yamllint new file mode 100644 index 000000000..882767605 --- /dev/null +++ b/roles/idrac_certificate/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/idrac_certificate/README.md b/roles/idrac_certificate/README.md new file mode 100644 index 000000000..5590fda29 --- /dev/null +++ b/roles/idrac_certificate/README.md @@ -0,0 +1,361 @@ +# idrac_certificate + +Role to manage the iDRAC certificates - Generate Certificate Signing Request, Import/Export certificates, and Reset configuration - for PowerEdge servers. + +## Requirements + +--- + +Requirements to develop and contribute to the role. + +### Development + +``` +ansible +docker +molecule +python +``` + +### Production + +Requirements to use the role. + +``` +ansible +python +``` + +## Ansible collections + +Collections required to use the role. + +``` +dellemc.openmanage +``` + +## Role Variables + +--- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameRequiredDefault ValueChoicesTypeDescription
hostnametruestr- iDRAC IP Address
usernametruestr- iDRAC username
passwordtruestr- iDRAC user password.
https_portfalse443int- iDRAC port.
validate_certsfalsetruebool- If C(false), the SSL certificates will not be validated.
- Configure C(false) only on personally controlled sites where self-signed certificates are used.
ca_pathfalsepath- The Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
https_timeoutfalse30int- The socket level timeout in seconds.
commandfalsegenerate_csr'import', 'export', 'generate_csr', 'reset'str- C(generate_csr), generate CSR. This requires I(cert_params) and I(certificate_path). +
- C(import), import the certificate file. This requires I(certificate_path). +
- C(export), export the certificate. This requires I(certificate_path). +
- C(reset), reset the certificate to default settings. This is applicable only for C(HTTPS). +
certificate_typefalseHTTPS'HTTPS', 'CA', 'CSC', 'CLIENT_TRUST_CERTIFICATE'str-Type of the iDRAC certificate: +
- C(HTTPS) The Dell self-signed SSL certificate. +
- C(CA) Certificate Authority(CA) signed SSL certificate. +
- C(CSC) The custom signed SSL certificate. +
- C(CLIENT_TRUST_CERTIFICATE) Client trust certificate.
certificate_pathfalsepath- Absolute path of the certificate file if I(command) is C(import). +
- Directory path with write permissions if I(command) is C(generate_csr) or C(export).
passpharsefalsestr- The passphrase string if the certificate to be imported is passphrase protected.
cert_paramsfalsedict
     common_namefalsestr- The common name of the certificate.
     organization_unitfalsetruestr- The name associated with an organizational unit. For example, department name.
     locality_namefalsestr- The city or other location where the entity applying for certification is located.
     state_namefalsestr- The state where the entity applying for certification is located.
     country_codefalsestr - The country code of the country where the entity applying for certification is located.
     email_addressfalsestr- The email associated with the CSR.
     organization_namefalsestr- The name associated with an organization.
     subject_alt_namefalse[]list- The alternative domain names associated with the request.
resource_idfalsestr- Redfish ID of the resource.
resetfalsetruebool- To reset the iDRAC after the certificate operation.
- This is applicable when I(command) is C(import) or C(reset).
waitfalse300bool- Maximum wait time for iDRAC to start after the reset, in seconds.
- This is applicable when I(command) is C(import) or C(reset) and I(reset) is C(True).
+ +## Fact variables + + + + + + + + + + + + + + + + +
NameSampleDescription
idrac_certificate_out{ +"certificate_path": "/root/Certs/192.168.0.1_202333_4130_HTTPS.pem", + "changed": false, + "msg": "Successfully performed the 'export' operation." +}Module output of the cerificate export job.
+ +## Examples + +--- + +``` +- name: Generate HTTPS certificate signing request + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "192.168.0.1" + username: "user_name" + password: "user_password" + ca_path: "/path/to/ca_cert.pem" + command: "generate_csr" + certificate_type: "HTTPS" + certificate_path: "/home/omam/mycerts" + cert_params: + common_name: "sample.domain.com" + organization_unit: "OrgUnit" + locality_name: "Bangalore" + state_name: "Karnataka" + country_code: "IN" + email_address: "admin@domain.com" + organization_name: "OrgName" + subject_alt_name: + - 192.198.2.1 +``` + +``` +- name: Importing certificate. + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "192.168.0.1" + username: "user_name" + password: "user_password" + ca_path: "/path/to/ca_cert.pem" + command: "import" + certificate_type: "HTTPS" + certificate_path: "/path/to/cert.pem" +``` + +``` +- name: Exporting certificate. + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "192.168.0.1" + username: "user_name" + password: "user_password" + ca_path: "/path/to/ca_cert.pem" + command: "export" + certificate_type: "HTTPS" + certificate_path: "/home/omam/mycert_dir" +``` + +``` +- name: Importing certificate. + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "192.168.0.1" + username: "user_name" + password: "user_password" + ca_path: "/path/to/ca_cert.pem" + command: "import" + certificate_type: "CSC" + certificate_path: "/path/to/cert.pem" +``` + +``` +- name: Exporting certificate. + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "192.168.0.1" + username: "user_name" + password: "user_password" + ca_path: "/path/to/ca_cert.pem" + command: "export" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "/home/omam/mycert_dir" +``` + +## Author Information + +--- + +Dell Technologies
+Shivam Sharma (Shivam.Sharma3@Dell.com) 2023 diff --git a/roles/idrac_certificate/defaults/main.yml b/roles/idrac_certificate/defaults/main.yml new file mode 100644 index 000000000..9d61363a0 --- /dev/null +++ b/roles/idrac_certificate/defaults/main.yml @@ -0,0 +1,8 @@ +--- +# defaults file for idrac_certificate + +https_port: 443 +validate_certs: true +https_timeout: 30 +certificate_type: "HTTPS" +command: generate_csr diff --git a/roles/idrac_certificate/handlers/main.yml b/roles/idrac_certificate/handlers/main.yml new file mode 100644 index 000000000..edfc1a30b --- /dev/null +++ b/roles/idrac_certificate/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for idrac_certificate diff --git a/roles/idrac_certificate/meta/argument_specs.yml b/roles/idrac_certificate/meta/argument_specs.yml new file mode 100644 index 000000000..9f038f3eb --- /dev/null +++ b/roles/idrac_certificate/meta/argument_specs.yml @@ -0,0 +1,106 @@ +--- +argument_specs: + main: + version_added: "7.4.0" + short_description: Role to manage the iDRAC certificates - Generate CSR, Import/Export certificates, and Reset configuration - for PowerEdge servers. + description: This role allows to generate certificate signing request, import, and export certificates on iDRAC. + options: + hostname: + required: true + type: str + description: iDRAC IP Address. + username: + required: true + type: str + description: iDRAC username. + password: + required: true + 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 C(5.0.0), the 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: str + https_timeout: + description: The socket level timeout in seconds. + type: int + default: 30 + command: + description: C(generate_csr), generate CSR. This requires I(cert_params) and I(certificate_path). + choices: ["import", "export", "generate_csr", "reset"] + default: "generate_csr" + type: str + certificate_type: + description: Type of the iDRAC certificate + - C(HTTPS) The Dell self-signed SSL certificate. + - (CA) Certificate Authority(CA) signed SSL certificate. + - C(CSC) The custom signed SSL certificate. + - C(CLIENT_TRUST_CERTIFICATE) Client trust certificate. + type: str + choices: ["HTTPS", "CA", "CSC", "CLIENT_TRUST_CERTIFICATE"] + default: "HTTPS" + certificate_path: + description: + - Absolute path of the certificate file if I(command) is C(import). + - Directory path with write permissions if I(command) is C(generate_csr) or C(export). + type: path + passphrase: + description: The passphrase string if the certificate to be imported is passphrase protected. + type: str + cert_params: + description: Certificate parameters to generate signing request. + type: dict + options: + common_name: + description: The common name of the certificate. + type: str + organization_unit: + description: The name associated with an organizational unit. For example, department name. + type: str + default: true + locality_name: + description: The city or other location where the entity applying for certification is located. + type: str + state_name: + description: The state where the entity applying for certification is located. + type: str + country_code: + description: The country code of the country where the entity applying for certification is located. + type: str + email_address: + description: The email associated with the CSR. + type: str + organization_name: + description: The name associated with an organization. + type: str + subject_alt_name: + description: The alternative domain names associated with the request. + type: list + elements: str + default: [] + resource_id: + description: Redfish ID of the resource. + type: str + reset: + description: + - To reset the iDRAC after the certificate operation. + - This is applicable when I(command) is C(import) or C(reset). + type: bool + default: true + wait: + description: + - Maximum wait time for iDRAC to start after the reset, in seconds. + - This is applicable when I(command) is C(import) or C(reset) and I(reset) is C(True). + type: int + default: 300 diff --git a/roles/idrac_certificate/meta/main.yml b/roles/idrac_certificate/meta/main.yml new file mode 100644 index 000000000..75a57d065 --- /dev/null +++ b/roles/idrac_certificate/meta/main.yml @@ -0,0 +1,55 @@ +galaxy_info: + author: "Shivam Sharma" + description: Role to manage the iDRAC certificates - Generate CSR, Import/Export certificates, and Reset configuration - for PowerEdge servers. + 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/roles/idrac_certificate/molecule/CA/converge.yml b/roles/idrac_certificate/molecule/CA/converge.yml new file mode 100644 index 000000000..2349c5ce5 --- /dev/null +++ b/roles/idrac_certificate/molecule/CA/converge.yml @@ -0,0 +1,54 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Export a CA certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "export" + certificate_type: "CA" + certificate_path: "{{ cert_export_path }}" + + - name: Setting up CA certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: ca_cert_file + no_log: true + + - name: Verifying CA export certificate + ansible.builtin.assert: + that: + - ca_cert_file.stat.exists + - not idrac_certificate_out.changed + - not idrac_certificate_out.failed + - idrac_certificate_out.msg == "Successfully performed the 'export' operation." + + - name: Import a CA certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CA" + certificate_path: "{{ ca_cert_file.stat.path }}" + + - name: Verifying CA import certificate + ansible.builtin.assert: + that: + - idrac_certificate_out.msg == "No changes found to be applied." or idrac_certificate_out.msg == "Successfully performed the 'import' operation." + - not idrac_certificate_out.failed diff --git a/roles/idrac_certificate/molecule/CA/molecule.yml b/roles/idrac_certificate/molecule/CA/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/CSC/converge.yml b/roles/idrac_certificate/molecule/CSC/converge.yml new file mode 100644 index 000000000..9f0a21267 --- /dev/null +++ b/roles/idrac_certificate/molecule/CSC/converge.yml @@ -0,0 +1,54 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Export a CSC certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "export" + certificate_type: "CSC" + certificate_path: "{{ cert_export_path }}" + + - name: Setting up CSC certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: csc_cert_file + no_log: true + + - name: Verifying CSC export certificate + ansible.builtin.assert: + that: + - csc_cert_file.stat.exists + - not idrac_certificate_out.changed + - not idrac_certificate_out.failed + - idrac_certificate_out.msg == "Successfully performed the 'export' operation." + + - name: Import a CSC certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CSC" + certificate_path: "{{ csc_cert_file.stat.path }}" + + - name: Verifying CSC import certificate + ansible.builtin.assert: + that: + - idrac_certificate_out.msg == "No changes found to be applied." or idrac_certificate_out.msg == "Successfully performed the 'import' operation." + - not idrac_certificate_out.failed diff --git a/roles/idrac_certificate/molecule/CSC/molecule.yml b/roles/idrac_certificate/molecule/CSC/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/CTC/converge.yml b/roles/idrac_certificate/molecule/CTC/converge.yml new file mode 100644 index 000000000..a2fb92efa --- /dev/null +++ b/roles/idrac_certificate/molecule/CTC/converge.yml @@ -0,0 +1,54 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Export a Client Trust Certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "export" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ cert_export_path }}" + + - name: Setting up Client Trust certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: ctc_cert_file + no_log: true + + - name: Verifying CTC export certificate + ansible.builtin.assert: + that: + - ctc_cert_file.stat.exists + - not idrac_certificate_out.changed + - not idrac_certificate_out.failed + - idrac_certificate_out.msg == "Successfully performed the 'export' operation." + + - name: Import a CTC certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ ctc_cert_file.stat.path }}" + + - name: Verifying CTC import certificate + ansible.builtin.assert: + that: + - idrac_certificate_out.msg == "No changes found to be applied." or idrac_certificate_out.msg == "Successfully performed the 'import' operation." + - not idrac_certificate_out.failed diff --git a/roles/idrac_certificate/molecule/CTC/molecule.yml b/roles/idrac_certificate/molecule/CTC/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/HTTPS/converge.yml b/roles/idrac_certificate/molecule/HTTPS/converge.yml new file mode 100644 index 000000000..ccacca561 --- /dev/null +++ b/roles/idrac_certificate/molecule/HTTPS/converge.yml @@ -0,0 +1,54 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Export a HTTPS certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "export" + certificate_type: "HTTPS" + certificate_path: "{{ cert_export_path }}" + + - name: Setting up HTTPS certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: https_cert_file + no_log: true + + - name: Verifying HTTPS export certificate + ansible.builtin.assert: + that: + - https_cert_file.stat.exists + - not idrac_certificate_out.changed + - not idrac_certificate_out.failed + - idrac_certificate_out.msg == "Successfully performed the 'export' operation." + + - name: Import a HTTPS certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "HTTPS" + certificate_path: "{{ https_cert_file.stat.path }}" + + - name: Verifying HTTPS import certificate + ansible.builtin.assert: + that: + - idrac_certificate_out.msg == "No changes found to be applied." or idrac_certificate_out.msg == "Successfully performed the 'import' operation." + - not idrac_certificate_out.failed diff --git a/roles/idrac_certificate/molecule/HTTPS/molecule.yml b/roles/idrac_certificate/molecule/HTTPS/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/default/converge.yml b/roles/idrac_certificate/molecule/default/converge.yml new file mode 100644 index 000000000..bc63914a4 --- /dev/null +++ b/roles/idrac_certificate/molecule/default/converge.yml @@ -0,0 +1,111 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Export a Client Trust Certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "export" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ cert_export_path }}" + + - name: Setting up Client Trust certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: ctc_cert_file + no_log: true + + - name: Import a Client Trust Certificate invalid path + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "/path/invalid-path/to/certificate.pem" + ignore_errors: true + register: res_err + + - name: Verifying Import a Client Trust Certificate invalid path + ansible.builtin.assert: + that: + - idrac_certificate_out.failed + - ('"[Errno 2] No such file or directory" in idrac_certificate_out.msg') + + - name: Import a Client Trust Certificate invalid certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ lookup('env', 'invalid_certificate') }}" + ignore_errors: true + register: res_err1 + + - name: Verifying Import a Client Trust Certificate invalid certificate + ansible.builtin.assert: + that: + - ('"HTTP Error 400" in idrac_certificate_out.msg') + - idrac_certificate_out.failed + + - name: Import a Client Trust Certificate invalid certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ lookup('env', 'invalid_certificate') }}" + ignore_errors: true + register: res_err2 + + - name: Verifying Import a Client Trust Certificate invalid certificate + ansible.builtin.assert: + that: + - ('"HTTP Error 400" in idrac_certificate_out.msg') + - idrac_certificate_out.failed + + - name: Import a Client Trust Certificate with invalid credentials + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'invalid_password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "import" + certificate_type: "CLIENT_TRUST_CERTIFICATE" + certificate_path: "{{ ctc_cert_file.stat.path }}" + ignore_errors: true + register: res_err3 + + - name: Verifying Import a Client Trust Certificate with invalid credentials + ansible.builtin.assert: + that: + - ('"HTTP Error 401" in idrac_certificate_out.msg') + - idrac_certificate_out.failed diff --git a/roles/idrac_certificate/molecule/default/molecule.yml b/roles/idrac_certificate/molecule/default/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/generateCSR/converge.yml b/roles/idrac_certificate/molecule/generateCSR/converge.yml new file mode 100644 index 000000000..844602223 --- /dev/null +++ b/roles/idrac_certificate/molecule/generateCSR/converge.yml @@ -0,0 +1,45 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Generate HTTPS CSR signing request + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "generate_csr" + certificate_type: "HTTPS" + certificate_path: "{{ cert_export_path }}" + cert_params: + common_name: "sample.domain.com" + organization_unit: "OrgUnit" + locality_name: "Bangalore" + state_name: "Karnataka" + country_code: "IN" + email_address: "admin@domain.com" + organization_name: "OrgName" + subject_alt_name: + - 192.198.2.1 + + - name: Setting up HTTPS CSR certificate path for exported file + ansible.builtin.stat: + path: "{{ idrac_certificate_out.certificate_path }}" + register: csr_cert_file + no_log: true + + - name: Verifying HTTPS generate CSR certificate + ansible.builtin.assert: + that: + - csr_cert_file.stat.exists + - not idrac_certificate_out.changed + - not idrac_certificate_out.failed + - idrac_certificate_out.msg == "Successfully performed the 'generate_csr' operation." diff --git a/roles/idrac_certificate/molecule/generateCSR/molecule.yml b/roles/idrac_certificate/molecule/generateCSR/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/molecule/reset/converge.yml b/roles/idrac_certificate/molecule/reset/converge.yml new file mode 100644 index 000000000..873415e6d --- /dev/null +++ b/roles/idrac_certificate/molecule/reset/converge.yml @@ -0,0 +1,26 @@ +--- +- name: Converge + hosts: all + gather_facts: false + vars: + ca_cert_path: "{{ lookup('env', 'ca_cert_path') }}" + cert_export_path: "{{ lookup('env', 'certificate_path') }}" + + tasks: + - name: Reset CA certificate + ansible.builtin.import_role: + name: idrac_certificate + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ca_path: "{{ ca_cert_path }}" + command: "reset" + certificate_type: "CA" + + - name: Verifying reset CA certificate + ansible.builtin.assert: + that: + - idrac_certificate_out.msg == "Successfully performed the 'reset' operation.iDRAC has been reset successfully." + - idrac_certificate_out.changed diff --git a/roles/idrac_certificate/molecule/reset/molecule.yml b/roles/idrac_certificate/molecule/reset/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_certificate/tasks/export.yml b/roles/idrac_certificate/tasks/export.yml new file mode 100644 index 000000000..bce62ac76 --- /dev/null +++ b/roles/idrac_certificate/tasks/export.yml @@ -0,0 +1,12 @@ +- name: Exporting certificate. + dellemc.openmanage.idrac_certificates: + idrac_ip: "{{ hostname }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path }}" + command: "export" + certificate_type: "{{ certificate_type }}" + certificate_path: "{{ certificate_path }}" + register: idrac_certificate_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_certificate/tasks/generate_csr.yml b/roles/idrac_certificate/tasks/generate_csr.yml new file mode 100644 index 000000000..4cdbdc79a --- /dev/null +++ b/roles/idrac_certificate/tasks/generate_csr.yml @@ -0,0 +1,22 @@ +--- +- name: Generate HTTPS certificate signing request + dellemc.openmanage.idrac_certificates: + idrac_ip: "{{ hostname }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path }}" + command: "generate_csr" + certificate_type: "{{ certificate_type }}" + certificate_path: "{{ certificate_path }}" + cert_params: + common_name: "{{ cert_params.common_name | default(omit) }}" + organization_unit: "{{ cert_params.organization_unit | default(omit) }}" + locality_name: "{{ cert_params.locality_name | default(omit) }}" + state_name: "{{ cert_params.state_name | default(omit) }}" + country_code: "{{ cert_params.country_code | default(omit) }}" + email_address: "{{ cert_params.email_address | default(omit) }}" + organization_name: "{{ cert_params.organization_name | default(omit) }}" + subject_alt_name: "{{ cert_params.subject_alt_name | default(omit) }}" + register: idrac_certificate_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_certificate/tasks/import.yml b/roles/idrac_certificate/tasks/import.yml new file mode 100644 index 000000000..b3691268b --- /dev/null +++ b/roles/idrac_certificate/tasks/import.yml @@ -0,0 +1,13 @@ +- name: Importing certificate. + dellemc.openmanage.idrac_certificates: + idrac_ip: "{{ hostname }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + validate_certs: "{{ validate_certs }}" + passphrase: "{{ passphrase | default(omit) }}" + ca_path: "{{ ca_path }}" + command: "import" + certificate_type: "{{ certificate_type }}" + certificate_path: "{{ certificate_path }}" + register: idrac_certificate_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_certificate/tasks/main.yml b/roles/idrac_certificate/tasks/main.yml new file mode 100644 index 000000000..1c586570b --- /dev/null +++ b/roles/idrac_certificate/tasks/main.yml @@ -0,0 +1,18 @@ +--- +# tasks file for idrac_certificate + +- name: Generate CSR + ansible.builtin.include_tasks: generate_csr.yml + when: command == "generate_csr" + +- name: Import certificate + ansible.builtin.include_tasks: import.yml + when: command == "import" + +- name: Export certificate + ansible.builtin.include_tasks: export.yml + when: command == "export" + +- name: Reset certificate + ansible.builtin.include_tasks: reset.yml + when: command == "reset" diff --git a/roles/idrac_certificate/tasks/reset.yml b/roles/idrac_certificate/tasks/reset.yml new file mode 100644 index 000000000..3d755d13e --- /dev/null +++ b/roles/idrac_certificate/tasks/reset.yml @@ -0,0 +1,12 @@ +--- +- name: Reset Certificate + dellemc.openmanage.idrac_certificates: + idrac_ip: "{{ hostname }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path }}" + command: "reset" + certificate_type: "HTTPS" + register: idrac_certificate_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_certificate/tests/inventory b/roles/idrac_certificate/tests/inventory new file mode 100644 index 000000000..2fbb50c4a --- /dev/null +++ b/roles/idrac_certificate/tests/inventory @@ -0,0 +1 @@ +localhost diff --git a/roles/idrac_certificate/tests/test.yml b/roles/idrac_certificate/tests/test.yml new file mode 100644 index 000000000..bdd3628e3 --- /dev/null +++ b/roles/idrac_certificate/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: This role is to generate certificate signing request, import, and export certificates on iDRAC. +- hosts: localhost + remote_user: root + roles: + - idrac_certificate diff --git a/roles/idrac_certificate/vars/main.yml b/roles/idrac_certificate/vars/main.yml new file mode 100644 index 000000000..70ba83636 --- /dev/null +++ b/roles/idrac_certificate/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for idrac_certificate diff --git a/roles/idrac_gather_facts/.yamllint b/roles/idrac_gather_facts/.yamllint new file mode 100644 index 000000000..882767605 --- /dev/null +++ b/roles/idrac_gather_facts/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/idrac_gather_facts/README.md b/roles/idrac_gather_facts/README.md new file mode 100644 index 000000000..24a70610b --- /dev/null +++ b/roles/idrac_gather_facts/README.md @@ -0,0 +1,326 @@ +# idrac_gather_facts + +Role to gather facts from iDRAC + +## Requirements +------------ + +### Development +Requirements to develop and contribute to the role. +``` +python +ansible +molecule +docker +``` +### Production +Requirements to use the role. +``` +python +ansible +jmespath +``` +### Ansible collections +Collections required to use the role. +``` +dellemc.openmanage +ansible.utils +``` + +## Role Variables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameRequiredDefault ValueChoicesTypeDescription
hostnametruestr- iDRAC IP Address
usernametruestr- iDRAC username
passwordtruestr- iDRAC user password.
https_portfalse443int- iDRAC port.
validate_certsfalsetruebool- 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.
ca_pathfalsepath- The Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
http_timeoutfalse30int- The socket level timeout in seconds.
computer_system_idfalsestr- Computer system id.
manager_idfalsestr- Manager/BMC id.
targetfalse- System
- System
- BIOS
- Controller
- CPU
- Enclosure
- EnclosureEMM
- Fan
+ - Firmware
- HostNIC
- License
- Memory
- NIC
- PCIeSSDBackPlane
+ - PowerSupply
- PresenceAndStatusSensor
- Sensors_Battery
- Sensors_Intrusion
+ - Sensors_Voltage
- VirtualDisk
- PCIeDevice
- PhysicalDisk
- SystemMetrics
list- I(target) component for which information needs to be gathered.
+ +## Fact variables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameSampleDescription
system{"BIOSReleaseDate": "03/22/2022", "BaseBoardChassisSlot": "1", "BatteryRollupStatus": "OK", "BladeGeometry": "SingleWidth,FullHeight", "CMCIP": "100.96.25.200", "CPURollupStatus": "Unknown", "ChassisModel": "", "ChassisName": "", "ChassisServiceTag": "6H8K6Z2", "ChassisSystemHeightUnit": 7, "CurrentRollupStatus": "OK", "EstimatedExhaustTemperatureCelsius": 255, "EstimatedSystemAirflowCFM": 255, "ExpressServiceCode": "14089561166", "FanRollupStatus": null, "IDSDMRollupStatus": null, "Id": "System.Embedded.1", "IntrusionRollupStatus": null, "IsOEMBranded": "False", "LastSystemInventoryTime": "2019-08-09T13:23:32+00:00", "LastUpdateTime": "2022-06-10T20:19:30+00:00", "LicensingRollupStatus": "OK", "ManagedSystemSize": "7 U", "MaxCPUSockets": 2, "MaxDIMMSlots": 24, "MaxPCIeSlots": 3, "MemoryOperationMode": "OptimizerMode", "Name": "DellSystem", "NodeID": "6H0K6Z2", "PSRollupStatus": null, "PlatformGUID": "325a364f-c0b6-4b80-3010-00484c4c4544", "PopulatedDIMMSlots": 2, "PopulatedPCIeSlots": 3, "PowerCapEnabledState": "Disabled", "SDCardRollupStatus": "OK", "SELRollupStatus": "OK", "ServerAllocationWatts": 18, "ServerOS.1.HostName": "MINWINPC", "ServerOS.1.OEMOSVersion": "", "ServerOS.1.OSName": "", "ServerOS.1.OSVersion": "", "ServerOS.1.ProductKey": "", "ServerOS.1.ServerPoweredOnTime": 0, "StorageRollupStatus": "OK", "SysMemErrorMethodology": "Multi-bitECC", "SysMemFailOverState": "NotInUse", "SysMemLocation": "SystemBoardOrMotherboard", "SysMemPrimaryStatus": "OK", "SystemGeneration": "14G Modular", "SystemID": 1893, "SystemRevision": "I", "TempRollupStatus": "OK", "TempStatisticsRollupStatus": "OK", "UUID": "4c4c4544-0048-3010-804b-b6c04f365a32", "VoltRollupStatus": "OK", "smbiosGUID": "44454c4c-4800-1030-804b-b6c04f365a32"}Response facts details for system and operating system.
bios{"@Redfish.Settings": {"SupportedApplyTimes": ["OnReset", "AtMaintenanceWindowStart", "InMaintenanceWindowOnReset"]}, "Attributes": {"AcPwrRcvry": "Last", "AdddcSetting": "Disabled", "AesNi": "Enabled", "AssetTag": "", "AuthorizeDeviceFirmware": "Disabled", "AvxIccpPregrant": "IccpHeavy128", "BootMode": "Bios", "BootSeqRetry": "Enabled", "CECriticalSEL": "Disabled", "ConTermType": "Vt100Vt220", "ControlledTurbo": "Disabled", "ControlledTurboMinusBin": 0, "CorrEccSmi": "Enabled", "CpuInterconnectBusLinkPower": "Enabled", "CpuInterconnectBusSpeed": "MaxDataRate", "CurrentEmbVideoState": "Enabled", "DcuIpPrefetcher": "Enabled", "DcuStreamerPrefetcher": "Enabled", "DeadLineLlcAlloc": "Enabled", "DellWyseP25BIOSAccess": "Enabled", "DirectoryAtoS": "Disabled", "DramRefreshDelay": +"Performance", "DynamicCoreAllocation": "Disabled", "EmbSata": "AhciMode", "EmbVideo": "Enabled", "EnergyPerformanceBias": "BalancedPerformance", "ErrPrompt": "Enabled", "ExtSerialConnector": "Serial1", "FailSafeBaud": "115200", "ForceInt10": "Disabled", "GenericUsbBoot": "Disabled", "HddFailover": "Disabled", "HddPlaceholder": "Disabled", "InBandManageabilityInterface": "Enabled", "IntelTxt": "Off", "InternalUsb": "On", "IoatEngine": "Disabled", "LlcPrefetch": "Disabled", "MemFrequency": "MaxPerf", "MemOpMode": "OptimizerMode", "MemPatrolScrub": "Standard", "MemRefreshRate": "1x", "MemTest": "Disabled", "MemoryMappedIOH": "56TB", "MmioAbove4Gb": "Enabled", "MonitorMwait": "Enabled", "NativeTrfcTiming": "Enabled", "NodeInterleave": "Disabled", "NumLock": "On", "NvmeMode": "NonRaid", "OneTimeBootMode": "Disabled", "OneTimeBootSeqDev": "Floppy.iDRACVirtual.1-1", "OneTimeHddSeqDev": "", "OppSrefEn": "Disabled", "OsWatchdogTimer": "Disabled", "PCIRootDeviceUnhide": "Disabled", "PPROnUCE": "Enabled", "PasswordStatus": "Unlocked", "PcieAspmL1": "Enabled", "PowerCycleRequest": "None", "Proc1Brand": "Intel(R) Xeon(R) Bronze 3204 CPU @ 1.90GHz", "Proc1Id": "6-55-7", "Proc1L2Cache": "6x1 MB", "Proc1L3Cache": "8448 KB", "Proc1MaxMemoryCapacity": "1 TB", "Proc1Microcode": "0x5003302", "Proc1NumCores": 6, "Proc2Brand": "Intel(R) Xeon(R) Bronze 3204 CPU @ 1.90GHz", "Proc2Id": "6-55-7", "Proc2L2Cache": "6x1 MB", "Proc2L3Cache": "8448 KB", "Proc2MaxMemoryCapacity": "1 TB", "Proc2Microcode": "0x5003302", "Proc2NumCores": 6, "ProcAdjCacheLine": "Enabled", "ProcBusSpeed": "9.60 GT/s", "ProcC1E": "Enabled", "ProcCStates": "Enabled", "ProcConfigTdp": "Nominal", "ProcCoreSpeed": "1.90 GHz", "ProcCores": "All", "ProcHwPrefetcher": "Enabled", "ProcPwrPerf": "SysDbpm", "ProcVirtualization": "Enabled", "ProcX2Apic": "Enabled", "PwrButton": "Enabled", "RedirAfterBoot": "Enabled", "RedundantOsBoot": "Disabled", "RedundantOsLocation": "None", "RedundantOsState": "Visible", "SHA256SetupPassword": "", "SHA256SetupPasswordSalt": "", "SHA256SystemPassword": "", "SHA256SystemPasswordSalt": "", "SataPortA": "Auto", "SataPortACapacity": "N/A", "SataPortADriveType": "Unknown Device", "SataPortAModel": "Unknown", "SataPortB": "Auto", "SataPortBCapacity": "N/A", "SataPortBDriveType": "Unknown Device", "SataPortBModel": "Unknown", "SataPortC": "Auto", "SataPortCCapacity": "N/A", "SataPortCDriveType": "Unknown Device", "SataPortCModel": "Unknown", "SataPortD": "Auto", "SataPortDCapacity": "N/A", "SataPortDDriveType": "Unknown Device", "SataPortDModel": "Unknown", "SataPortE": "Auto", "SataPortECapacity": "N/A", "SataPortEDriveType": "Unknown Device", "SataPortEModel": "Unknown", "SataPortF": "Auto", "SataPortFCapacity": "N/A", "SataPortFDriveType": "Unknown Device", "SataPortFModel": "Unknown", "SecureBoot": "Disabled", "SecureBootMode": "DeployedMode", "SecureBootPolicy": "Standard", "SecurityFreezeLock": "Enabled", "SerialComm": "Off", "SerialPortAddress": "Com1", "SetBootOrderDis": "", "SetBootOrderEn": "Floppy.iDRACVirtual.1-1,Optical.iDRACVirtual.1-1", "SetBootOrderFqdd1": "", "SetBootOrderFqdd10": "", "SetBootOrderFqdd11": "", "SetBootOrderFqdd12": "", "SetBootOrderFqdd13": "", "SetBootOrderFqdd14": "", "SetBootOrderFqdd15": "", "SetBootOrderFqdd16": "", "SetBootOrderFqdd2": "", "SetBootOrderFqdd3": "", "SetBootOrderFqdd4": "", "SetBootOrderFqdd5": "", "SetBootOrderFqdd6": "", "SetBootOrderFqdd7": "", "SetBootOrderFqdd8": "", "SetBootOrderFqdd9": "", "SetLegacyHddOrderFqdd1": "", "SetLegacyHddOrderFqdd10": "", "SetLegacyHddOrderFqdd11": "", "SetLegacyHddOrderFqdd12": "", "SetLegacyHddOrderFqdd13": "", "SetLegacyHddOrderFqdd14": "", "SetLegacyHddOrderFqdd15": "", "SetLegacyHddOrderFqdd16": "", "SetLegacyHddOrderFqdd2": "", "SetLegacyHddOrderFqdd3": "", "SetLegacyHddOrderFqdd4": "", "SetLegacyHddOrderFqdd5": "", "SetLegacyHddOrderFqdd6": "", "SetLegacyHddOrderFqdd7": "", "SetLegacyHddOrderFqdd8": +"", "SetLegacyHddOrderFqdd9": "", "SetupPassword": null, "Slot1": "Enabled", "Slot2": "Enabled", "Slot3": "Enabled", "SnoopHldOff": "Roll2KCycles", "SriovGlobalEnable": "Disabled", "SubNumaCluster": "Disabled", "SysMemSize": "32 GB", "SysMemSpeed": "2133 Mhz", "SysMemType": "ECC DDR4", "SysMemVolt": "1.20 V", "SysMfrContactInfo": "www.dell.com", "SysPassword": null, "SysProfile": "PerfPerWattOptimizedDapc", "SystemBiosVersion": "2.14.2", "SystemCpldVersion": "1.0.4", "SystemManufacturer": "Dell Inc.", "SystemMeVersion": "4.1.4.700", "SystemModelName": "PowerEdge MX740c", "SystemServiceTag": "6H0K6Z2", "TpmCommand": "None", "TpmFirmware": "TpmFirmware", "TpmInfo": "Type: 1.2-NTC", "TpmPpiBypassClear": "Disabled", "TpmPpiBypassProvision": "Disabled", "TpmSecurity": "Off", "TpmStatus": "Unknown", "UefiComplianceVersion": "2.7", "UefiVariableAccess": "Standard", "UncoreFrequency": "DynamicUFS", "UpiPrefetch": "Enabled", "UsbManagedPort": "On", "UsbPorts": "AllOn", "VideoMem": "16 MB", "WorkloadProfile": "NotAvailable", "WriteCache": "Disabled", "WriteDataCrc": "Disabled"}Response facts details for bios.
controller[{"AlarmState": "AlarmNotPresent", "AutoConfigBehavior": "Off", "BootVirtualDiskFQDD": null, "CacheSizeInMB": 8192, "CachecadeCapability": "NotSupported", "ConnectorCount": 4, "ControllerFirmwareVersion": "51.16.0-4076", "CurrentControllerMode": "RAID", "Description": "An instance of DellController will have RAID Controller specific data.", "Device": "0", "DeviceCardDataBusWidth": "8x or x8", "DeviceCardSlotLength": "Other", "DeviceCardSlotType": "PCI Express Gen3 x16", "DriverVersion": null, "EncryptionCapability": "LocalKeyManagementCapable", "EncryptionMode": "LocalKeyManagement", "Id": "RAID.Mezzanine.1C-1", "KeyID": "Root@123", "LastSystemInventoryTime": "2019-08-09T13:23:32+00:00", "LastUpdateTime": "2022-09-23T23:44:26+00:00", "MaxAvailablePCILinkSpeed": null, "MaxPossiblePCILinkSpeed": null, "Name": "DellController", "PCISlot": 6, "PatrolReadState": "Unknown", "PersistentHotspare": "Disabled", "RealtimeCapability": "Incapable", "RollupStatus": "Unknown", "SASAddress": "54CD98F03C1A9400", "SecurityStatus": "SecurityKeyAssigned", "SharedSlotAssignmentAllowed": "NotAllowed", "SlicedVDCapability": "Supported", "SupportControllerBootMode": "NotSupported", "SupportEnhancedAutoForeignImport": "Supported", "SupportRAID10UnevenSpans": "Supported", "SupportsLKMtoSEKMTransition": "No", "T10PICapability": "NotSupported"}]Response facts details for controller.
cpu[{"Description": "Represents the properties of a Processor attached to this System", "Id": "CPU.Socket.1", "InstructionSet": "x86-64", "Manufacturer": "Intel", "MaxSpeedMHz": 4000, "Model": "Intel(R) Xeon(R) Bronze 3204 CPU @ 1.90GHz", "Name": "CPU 1", "Oem": {"Dell": {"DellAccelerators": null, "DellProcessor": {"CPUFamily": "Intel(R)Xeon(TM)", "CPUStatus": "CPUEnabled", "Cache1Associativity": "8-WaySet-Associative", "Cache1ErrorMethodology": "Parity", "Cache1InstalledSizeKB": 384, "Cache1Level": "L1", "Cache1Location": "Internal", "Cache1PrimaryStatus": "OK", "Cache1SRAMType": "Unknown", "Cache1SizeKB": 384, "Cache1Type": "Unified", "Cache1WritePolicy": "WriteBack", "Cache2Associativity": "16-WaySet-Associative", "Cache2ErrorMethodology": "Single-bitECC", "Cache2InstalledSizeKB": 6144, "Cache2Level": "L2", "Cache2Location": "Internal", "Cache2PrimaryStatus": "OK", "Cache2SRAMType": "Unknown", "Cache2SizeKB": 6144, "Cache2Type": "Unified", "Cache2WritePolicy": "WriteBack", "Cache3Associativity": "FullyAssociative", "Cache3ErrorMethodology": "Single-bitECC", "Cache3InstalledSizeKB": 8448, "Cache3Level": "L3", "Cache3Location": "Internal", "Cache3PrimaryStatus": "OK", "Cache3SRAMType": "Unknown", "Cache3SizeKB": 8448, "Cache3Type": "Unified", "Cache3WritePolicy": "WriteBack", "CurrentClockSpeedMhz": 1900, "ExternalBusClockSpeedMhz": 9600, "HyperThreadingCapable": "No", "HyperThreadingEnabled": "No", "Id": "CPU.Socket.1", "LastSystemInventoryTime": "2019-08-09T13:23:32+00:00", "LastUpdateTime": "2021-09-14T20:31:00+00:00", "Name": "DellProcessor", "TurboModeCapable": "No", "TurboModeEnabled": "No", "VirtualizationTechnologyCapable": "Yes", "VirtualizationTechnologyEnabled": "Yes", "Volts": "1.8"}, "PowerMetrics": null, "ThermalMetrics": null}}, "OperatingSpeedMHz": 1900, "ProcessorArchitecture": "x86", "ProcessorId": {"EffectiveFamily": "6", "EffectiveModel": "85", "IdentificationRegisters": "0x00050657", "MicrocodeInfo": "0x5003302", "Step": "7", "VendorId": "GenuineIntel"}, "ProcessorType": "CPU", "Socket": "CPU.Socket.1", "Status": {"Health": null, "State": "UnavailableOffline"}, "TotalCores": 6, "TotalEnabledCores": 6, "TotalThreads": 6, "TurboState": "Disabled", "Version": "Model 85 Stepping 7"}]Response facts details for cpu.
enclosure[{"AssetName": null, "Connector": 0, "Id": "Enclosure.Internal.0-0:RAID.Mezzanine.1C-1", "LastSystemInventoryTime": "2019-08-09T13:23:32+00:00", "LastUpdateTime": "2022-09-23T23:44:26+00:00", "Name": "DellEnclosure", "ServiceTag": null, "SlotCount": 6, "TempProbeCount": 0, "Version": "4.35", "WiredOrder": 0}]Response facts details for enclosure.
enclosure_emm[{"DeviceDescription": "EMM.Slot.0:Enclosure.Modular.4:NonRAID.Mezzanine.1C-1", "FQDD": "EMM.Slot.0:Enclosure.Modular.4:NonRAID.Mezzanine.1C-1", "Id": "EMM.Slot.0:Enclosure.Modular.4:NonRAID.Mezzanine.1C-1", "InstanceID": "EMM.Slot.0:Enclosure.Modular.4:NonRAID.Mezzanine.1C-1", "Name": "DellEnclosureEMM", "PartNumber": null, "PrimaryStatus": "OK", "Revision": +"2.40", "State": "Ready"}]Response facts details for enclosure_emm.
fan[{"Description": "Represents fan properties of the chassis", "HotPluggable": true, "Id": "Fan.Embedded.6A", "Location": {"PartLocation": {"LocationType": "Bay", "ServiceLabel": "System Board Fan6A"}}, "Name": "Fan 6A", "PhysicalContext": "SystemBoard", "SpeedPercent": {"SpeedRPM": 11640}, "Status": {"Health": "OK", "State": "Enabled"}}]Response facts details for fan.
firmware[{"Description": "Represents Firmware Inventory", "Id": "Previous-108255-22.00.6__NIC.Embedded.2-1-1", "Name": "Broadcom Gigabit Ethernet BCM5720 - F4:02:70:B9:5A:29", "Oem": {"Dell": {"DellSoftwareInventory": {"BuildNumber": 0, "Classifications": ["Firmware"], "ComponentID": "108255", "ComponentType": "FRMW", "Description": "The DellSoftwareInventory resource is a representation of an available device firmware in the managed system.", "DeviceID": "165F", "ElementName": "Broadcom Gigabit Ethernet BCM5720 - F4:02:70:B9:5A:29", "HashValue": "56fa85676e6d570f714fb659f202371f1c570263b680e2d40d16059acfa9e3e6", "Id": "DCIM:PREVIOUS_0x23_701__NIC.Embedded.2-1-1", "IdentityInfoType": ["OrgID:ComponentType:VendorID:DeviceID:SubVendorID:SubDeviceID"], "IdentityInfoValue": ["DCIM:firmware:14E4:165F:1028:08FF"], +"InstallationDate": "NA", "IsEntity": true, "MajorVersion": 22, "MinorVersion": 0, "Name": "DellSoftwareInventory", "PLDMCapabilitiesDuringUpdate": "0x00000000", "PLDMFDPCapabilitiesDuringUpdate": "0x00000000", "RevisionNumber": 6, "RevisionString": null, "SidebandUpdateCapable": false, "Status": "AvailableForInstallation", "SubDeviceID": "08FF", "SubVendorID": "1028", "VendorID": "14E4", "impactsTPMmeasurements": true}}}, "ReleaseDate": "2022-01-07T00:00:00Z", "SoftwareId": "108255", "Status": {"Health": "OK", "State": "Enabled"}, "Updateable": true, "Version": "22.00.6"}, {"Description": "Represents Firmware Inventory", "Id": "Previous-159-1.7.5__BIOS.Setup.1-1", "Name": "BIOS", "Oem": {"Dell": {"DellSoftwareInventory": {"BuildNumber": 0, "Classifications": ["BIOS/FCode"], "ComponentID": "159", "ComponentType": "BIOS", "Description": "The DellSoftwareInventory resource is a representation of an available device firmware in the managed system.", "DeviceID": null, "ElementName": "BIOS", "HashValue": "37e196d6b1c25ffc58f1c5c5a80a748932d22ddfbf72eedda05fbe788f57d641", "Id": "DCIM:PREVIOUS_0x23_741__BIOS.Setup.1-1", "IdentityInfoType": ["OrgID:ComponentType:ComponentID"], "IdentityInfoValue": ["DCIM:BIOS:159"], "InstallationDate": "NA", "IsEntity": true, "MajorVersion": 1, "MinorVersion": 7, "Name": "DellSoftwareInventory", "PLDMCapabilitiesDuringUpdate": "0x00000000", "PLDMFDPCapabilitiesDuringUpdate": "0x00000000", "RevisionNumber": 5, "RevisionString": null, "SidebandUpdateCapable": false, "Status": "AvailableForInstallation", "SubDeviceID": null, "SubVendorID": null, "VendorID": null, "impactsTPMmeasurements": true}}}, "ReleaseDate": "2022-09-16T00:00:00Z", "SoftwareId": "159", "Status": {"Health": "OK", "State": "Enabled"}, "Updateable": true, "Version": "1.7.5"}, {"Description": "Represents Firmware Inventory", "Id": "Previous-25227-6.00.02.00__iDRAC.Embedded.1-1", "Name": "Integrated Dell Remote Access Controller", "Oem": {"Dell": {"DellSoftwareInventory": {"BuildNumber": 7, "Classifications": ["Firmware"], "ComponentID": "25227", "ComponentType": "FRMW", "Description": "The DellSoftwareInventory resource is a representation of an available device firmware in the managed system.", "DeviceID": null, "ElementName": "Integrated Dell Remote Access Controller", "HashValue": null, "Id": "DCIM:PREVIOUS_0x23_iDRAC.Embedded.1-1_0x23_IDRACinfo", "IdentityInfoType": ["OrgID:ComponentType:ComponentID"], "IdentityInfoValue": ["DCIM:firmware:25227"], "InstallationDate": "NA", "IsEntity": true, "MajorVersion": 6, "MinorVersion": 0, "Name": "DellSoftwareInventory", "PLDMCapabilitiesDuringUpdate": "0x00000000", "PLDMFDPCapabilitiesDuringUpdate": "0x00000000", "RevisionNumber": 2, "RevisionString": null, "SidebandUpdateCapable": false, "Status": "AvailableForInstallation", "SubDeviceID": null, "SubVendorID": null, "VendorID": null, "impactsTPMmeasurements": false}}}, "ReleaseDate": "2022-08-11T00:00:00Z", "SoftwareId": "25227", "Status": {"Health": "OK", "State": "Enabled"}, "Updateable": true, "Version": "6.00.02.00"}]Response facts details for firmware.
hostnic[{"Description": "Management for Host Interface", "ExternallyAccessible": false, "HostInterfaceType": "NetworkHostInterface", "Id": "Host.1", "InterfaceEnabled": false, "Name": "Managed Host Interface 1"}]Response facts details for hostnic.
license[{"AuthorizationScope": "Service", "Description": "iDRAC9 x5 Enterprise Evaluation License", "DownloadURI": "/redfish/v1/LicenseService/Licenses/1188PA_girish_narasimhap/DownloadURI", "EntitlementId": "1188PA_girish_narasimhap", "ExpirationDate": "2023-02-23T00:00:00-06:00", "Id": "1188PA_girish_narasimhap", "InstallDate": null, "LicenseInfoURI": "", "LicenseOrigin": "Installed", "LicenseType": "Trial", "Links": {}, "Name": "1188PA_girish_narasimhap", "Removable": true, "Status": {"Health": "Warning", "State": "Enabled"}}]Response facts details for license.
nic[{"AutoNeg": true, "Description": "Embedded NIC 1 Port 1 Partition 1", "EthernetInterfaceType": "Physical", "FQDN": null, "FullDuplex": true, "HostName": null, "IPv4Addresses": [], "IPv6AddressPolicyTable": [], "IPv6Addresses": [], "IPv6DefaultGateway": null, "IPv6StaticAddresses": [], "Id": "NIC.Embedded.1-1-1", "InterfaceEnabled": true, "LinkStatus": "LinkUp", "Links": {"Chassis": {}}, "MACAddress": "F4:02:70:B9:5A:28", "MTUSize": null, "MaxIPv6StaticAddresses": null, "Name": "System Ethernet Interface", "NameServers": [], "PermanentMACAddress": "F4:02:70:B9:5A:28", "SpeedMbps": 1000, "Status": {"Health": "OK", "State": "Enabled"}, "UefiDevicePath": "PciRoot(0x0)/Pci(0x1C,0x5)/Pci(0x0,0x0)", "VLAN": {}}, {"AutoNeg": false, "Description": "Embedded NIC 1 Port 2 Partition 1", "EthernetInterfaceType": "Physical", "FQDN": null, "FullDuplex": false, "HostName": null, "IPv4Addresses": [], "IPv6AddressPolicyTable": [], "IPv6Addresses": [], "IPv6DefaultGateway": null, "IPv6StaticAddresses": [], "Id": "NIC.Embedded.2-1-1", "InterfaceEnabled": true, "LinkStatus": "LinkDown", "Links": {"Chassis": {}}, "MACAddress": "F4:02:70:B9:5A:29", "MTUSize": null, "MaxIPv6StaticAddresses": null, "Name": "System Ethernet Interface", "NameServers": [], "PermanentMACAddress": "F4:02:70:B9:5A:29", "SpeedMbps": 0, "Status": {"Health": "OK", "State": "Enabled"}, "UefiDevicePath": "PciRoot(0x0)/Pci(0x1C,0x5)/Pci(0x0,0x1)", "VLAN": {}}]Response facts details for nic.
memory[{"AllowedSpeedsMHz": [3200], "Assembly": {}, "BaseModuleType": "RDIMM", "BusWidthBits": 72, "CacheSizeMiB": 0, "CapacityMiB": 8192, "DataWidthBits": 64, "Description": "DIMM A1", "DeviceLocator": "DIMM A1", "Enabled": true, "ErrorCorrection": "MultiBitECC", "FirmwareRevision": null, "Id": "DIMM.Socket.A1", "Links": {"Chassis": {}, "Oem": {"Dell": {"CPUAffinity": []}}, "Processors": []}, "LogicalSizeMiB": 0, "Manufacturer": "Hynix Semiconductor", "MaxTDPMilliWatts": [], "MemoryDeviceType": "DDR4", "MemorySubsystemControllerManufacturerID": null, "MemorySubsystemControllerProductID": null, "MemoryType": "DRAM", "Metrics": {}, "ModuleManufacturerID": "0xad80", "ModuleProductID": null, "Name": "DIMM A1", "NonVolatileSizeMiB": 0, "Oem": {"Dell": {"DellMemory": {"BankLabel": "A", "Id": "DIMM.Socket.A1", "LastSystemInventoryTime": "2023-01-31T12:00:45+00:00", "LastUpdateTime": "2021-02-11T21:30:07+00:00", "ManufactureDate": "Mon May 04 07:00:00 2020 UTC", "MemoryTechnology": "DRAM", "Model": "DDR4 DIMM", "Name": "DellMemory", "RemainingRatedWriteEndurancePercent": null, "SystemEraseCapability": "NotSupported"}}}, "OperatingMemoryModes": ["Volatile"], "OperatingSpeedMhz": 2666, "PartNumber": "HMA81GR7CJR8N-XN", "RankCount": 1, "SerialNumber": "83E6758F", "Status": {"Health": "OK", "State": "Enabled"}, "VolatileSizeMiB": 8192}]Response facts details for memory.
backplane[{"Description": "An instance of DellPCIeSSDBackPlane will have PCIeSSD back plane specific data.", "FirmwareVersion": "3.72", "Id": "Enclosure.Internal.0-2", +"Name": "DellPCIeSSDBackPlane", "PCIExpressGeneration": "Gen 4", "SlotCount": 8, "WiredOrder": 2}]Response facts details for backplane.
power_supply[{"Assembly": {}, "Description": "An instance of PowerSupply", "FirmwareVersion": "00.17.28", "HotPluggable": true, "Id": "PSU.Slot.1", "InputNominalVoltageType": "AC240V", "InputRanges": [{"CapacityWatts": 1400.0, "NominalVoltageType": "AC240V"}], "LineInputStatus": "Normal", "Manufacturer": "DELL", "Metrics": {}, "Model": "PWR SPLY,1400W,RDNT,LTON", "Name": "PS1 Status", "Oem": {"Dell": {"DellPowerSupply": {"ActiveInputVoltage": "Unknown", "IsSwitchingSupply": true, "OperationalStatus": ["OK"], "RequestedState": "NotApplicable"}, "DellPowerSupplyView": {"DetailedState": "Presence Detected", "DeviceDescription": "Power Supply 1", "LastSystemInventoryTime": "2023-01-31T12:00:45+00:00", "LastUpdateTime": "2023-03-09T15:58:41+00:00", "PMBusMonitoring": "Capable", "Range1MaxInputPowerWatts": 1568, "RedMinNumberNeeded": 1, "RedTypeOfSet": ["N+1", "Sparing"], "RedundancyStatus": "Unknown"}}}, "PartNumber": "01CW9GA03", "PowerCapacityWatts": 1400.0, "PowerSupplyType": "AC", "SerialNumber": "CNLOD0007E256D", "SparePartNumber": "01CW9GA03", "Status": {"Health": "OK", "State": "Enabled"}}]Response facts details for power_supply.
presence_and_status_sensor[{"CurrentState": "Present", "Description": "An instance of DellPresenceAndStatusSensor will have presence and status sensor specific data.", +"DeviceID": "iDRAC.Embedded.1#VFLASHSD", "ElementName": "VFLASH SD", "Id": "iDRAC.Embedded.1_0x23_VFLASHSD", "Name": "DellPresenceAndStatusSensor", "SensorType": "Other"}]Response facts details for presence_and_status_sensor.
sensor_battery{"CurrentState": "Good", "Description": "An instance of DellSensor will represent a sensor, a hardware device that is capable of measuring the characteristics of a physical property.", "ElementName": "System Board CMOS Battery", "EnabledState": "Enabled", "HealthState": "OK", "Id": "iDRAC.Embedded.1_0x23_SystemBoardCMOSBattery", "Links": {"ComputerSystem": {}}, "Name": "DellSensor", "SensorType": "Other"}Response facts details for sensor_battery.
intrusion_sensor{"PhysicalSecurity": {"IntrusionSensor": "Normal"}}Response facts details for intrusion_sensor.
virtual_disk[{"@Redfish.Settings": {"SettingsObject": {}, "SupportedApplyTimes": ["Immediate", "OnReset", "AtMaintenanceWindowStart", "InMaintenanceWindowOnReset"]}, "BlockSizeBytes": 512, "CapacityBytes": 240057409536, "Description": "Disk 0 on Integrated AHCI controller 1", "DisplayName": null, "Encrypted": null, "EncryptionTypes": [], "Id": "Disk.Direct.0-0:AHCI.Integrated.1-1", "Identifiers": [], "MediaSpanCount": null, "Name": "SSD 0", "Operations": [], "OptimumIOSizeBytes": null, "RAIDType": null, "ReadCachePolicy": null, "Status": {"Health": "OK", "HealthRollup": "OK", "State": "Enabled"}, "VolumeType": "RawDevice", "WriteCachePolicy": null}, {"@Redfish.Settings": {"SettingsObject": {}, "SupportedApplyTimes": ["Immediate", "OnReset", "AtMaintenanceWindowStart", "InMaintenanceWindowOnReset"]}, "BlockSizeBytes": 512, "CapacityBytes": 240057409536, "Description": "Disk 1 on Integrated AHCI controller 1", "DisplayName": null, "Encrypted": null, "EncryptionTypes": [], "Id": "Disk.Direct.1-1:AHCI.Integrated.1-1", "Identifiers": [], "MediaSpanCount": null, "Name": "SSD 1", "Operations": [], "OptimumIOSizeBytes": null, "RAIDType": null, "ReadCachePolicy": null, "Status": {"Health": "OK", "HealthRollup": "OK", "State": "Enabled"}, "VolumeType": "RawDevice", "WriteCachePolicy": null}]Response facts details for virtual_disk.
pcie_device{"AssetTag": null, "Description": "Integrated Matrox G200eW3 Graphics Controller", "DeviceType": "SingleFunction", "FirmwareVersion": "", "Id": "3-0", "Manufacturer": "Matrox Electronics Systems Ltd.", "Model": null, "Name": "Integrated Matrox G200eW3 Graphics Controller", "PCIeFunctions": {}, "PartNumber": null, "SKU": null, "SerialNumber": null, "Status": {"Health": "OK", "HealthRollup": "OK", "State": "Enabled"}}, {"AssetTag": null, "Description": "PERC H730P MX", "DeviceType": "SingleFunction", "FirmwareVersion": "25.5.9.0001", "Id": "59-0", "Manufacturer": "Broadcom / LSI", "Model": null, "Name": "PERC H730P MX", "PCIeFunctions": {}, "PartNumber": "02RFJJ", "SKU": null, "SerialNumber": "CNFCP0095L005X", "Status": {"Health": "OK", "HealthRollup": "OK", "State": "Enabled"}}]Response facts details for pcie_device.
physical_disk[{"BlockSizeBytes": 512, "CapableSpeedGbs": 6, "CapacityBytes": 240057409536, "Description": "Disk 1 on Integrated AHCI controller 1", "EncryptionAbility": "None", "EncryptionStatus": "Unencrypted", "FailurePredicted": false, "HotspareType": "None", "Id": "Disk.Direct.1-1:AHCI.Integrated.1-1", "Identifiers": [{"DurableName": null, "DurableNameFormat": null}], "Identifiers@odata.count": 1, "Location": [], "LocationIndicatorActive": null, "Manufacturer": "INTEL", "MediaType": "SSD", "Model": "SSDSCKJB240G7R", "Name": "SSD 1", "NegotiatedSpeedGbs": 6, "Oem": {"Dell": {"DellPhysicalDisk": {"AvailableSparePercent": null, "Certified": "NotApplicable", "Connector": 0, "CryptographicEraseCapable": "Capable", "Description": "An instance of DellPhysicalDisk will have Physical Disk specific data.", "DeviceProtocol": null, "DeviceSidebandProtocol": null, "DriveFormFactor": "M.2", "EncryptionProtocol": "None", "ErrorDescription": null, "ErrorRecoverable": "NotApplicable", "ForeignKeyIdentifier": null, "FreeSizeInBytes": 240057409536, "Id": "Disk.Direct.1-1:AHCI.Integrated.1-1", "LastSystemInventoryTime": "2023-03-04T05:50:09+00:00", "LastUpdateTime": "2023-02-15T16:32:30+00:00", "ManufacturingDay": 0, "ManufacturingWeek": 0, "ManufacturingYear": 0, "Name": "DellPhysicalDisk", "NonRAIDDiskCachePolicy": "Unknown", "OperationName": "None", "OperationPercentCompletePercent": 0, "PCIeCapableLinkWidth": "None", "PCIeNegotiatedLinkWidth": "None", "PPID": +"TW-0919J9-PIHIT-8AB-02K7-A00", "PowerStatus": "On", "PredictiveFailureState": "SmartAlertAbsent", "ProductID": null, "RAIDType": "Unknown", "RaidStatus": "NonRAID", "SASAddress": "Not Applicable", "Slot": 1, "SystemEraseCapability": "CryptographicErasePD", "T10PICapability": "NotSupported", "UsedSizeInBytes": 0, "WWN": "Not Applicable"}}}, "Operations": [], "PartNumber": "TW-0919J9-PIHIT-8AB-02K7-A00", "PhysicalLocation": {"PartLocation": {"LocationOrdinalValue": 1, "LocationType": "Slot"}}, "PredictedMediaLifeLeftPercent": 100, "Protocol": "SATA", "Revision": "N201DL43", "RotationSpeedRPM": null, "SerialNumber": "PHDW8396015V240E", "Status": {"Health": "OK", "HealthRollup": "OK", "State": "Enabled"}, "WriteCacheEnabled": false}]Response facts details for physical_disk.
+ +## Examples +----- + +``` +- name: iDRAC gather facts for System, BIOS, Controller, CPU, Enclosure. + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: + - System + - BIOS + - Controller + - CPU + - Enclosure +``` +``` +- name: iDRAC gather facts for EnclosureEMM, Fan, Firmware, HostNIC, License. + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + idrac_ip: "192.1.2.1" + idrac_user: "username" + idrac_password: "password" + ca_path: "/path/to/ca_cert.pem" + target: + - EnclosureEMM + - Fan + - Firmware + - HostNIC + - License +``` + +``` +- name: iDRAC gather facts for Memory, NIC, PCIeSSDBackPlane, PowerSupply, PresenceAndStatusSensor. + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + idrac_ip: "192.1.2.1" + idrac_user: "username" + idrac_password: "password" + ca_path: "/path/to/ca_cert.pem" + target: + - Memory + - NIC + - PCIeSSDBackPlane + - PowerSupply + - PresenceAndStatusSensor +``` + +``` +- name: iDRAC gather facts for Sensors_Battery, Sensors_Intrusion, Sensors_Voltage, VirtualDisk, PCIeDevice, PhysicalDisk, SystemMetrics. + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + idrac_ip: "192.1.2.1" + idrac_user: "username" + idrac_password: "password" + ca_path: "/path/to/ca_cert.pem" + target: + - Sensors_Battery + - Sensors_Intrusion + - Sensors_Voltage + - VirtualDisk + - PCIeDevice + - PhysicalDisk + - SystemMetrics +``` + +## Author Information +------------------ + +Dell Technologies
+Felix Stephen A (felix_s@dell.com) 2023 diff --git a/roles/idrac_gather_facts/defaults/main.yml b/roles/idrac_gather_facts/defaults/main.yml new file mode 100644 index 000000000..9ea74ef52 --- /dev/null +++ b/roles/idrac_gather_facts/defaults/main.yml @@ -0,0 +1,8 @@ +--- +https_port: 443 +validate_certs: true +http_timeout: 30 +target: + - System +computer_system_id: "" +manager_id: "" diff --git a/roles/idrac_gather_facts/handlers/main.yml b/roles/idrac_gather_facts/handlers/main.yml new file mode 100644 index 000000000..033de9080 --- /dev/null +++ b/roles/idrac_gather_facts/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for idrac_gather_facts diff --git a/roles/idrac_gather_facts/meta/argument_specs.yml b/roles/idrac_gather_facts/meta/argument_specs.yml new file mode 100644 index 000000000..7265cb523 --- /dev/null +++ b/roles/idrac_gather_facts/meta/argument_specs.yml @@ -0,0 +1,75 @@ +--- +argument_specs: + main: + version_added: "7.4.0" + short_description: Role to get the facts from the iDRAC Server. + description: Role to fetch the server facts about a different components available in the PowerEdge Servers. + options: + hostname: + required: true + type: str + description: iDRAC IP Address. + username: + required: true + type: str + description: iDRAC username. + password: + required: true + 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 + computer_system_id: + description: Computer system id + type: str + manager_id: + description: Manager/BMC id + type: str + target: + description: + - I(target) component for which information needs to be gathered. + type: list + choices: + [ + "IDRAC", + "System", + "BIOS", + "Controller", + "CPU", + "Enclosure", + "EnclosureEMM", + "Fan", + "Firmware", + "HostNIC", + "License", + "Memory", + "NIC", + "PCIeSSDBackPlane", + "PowerSupply", + "PresenceAndStatusSensor", + "Sensors_Battery", + "Sensors_Intrusion", + "Sensors_Voltage", + "VirtualDisk", + "PCIeDevice", + "PhysicalDisk", + "SystemMetrics", + ] + default: System diff --git a/roles/idrac_gather_facts/meta/main.yml b/roles/idrac_gather_facts/meta/main.yml new file mode 100644 index 000000000..690bd51a0 --- /dev/null +++ b/roles/idrac_gather_facts/meta/main.yml @@ -0,0 +1,54 @@ +galaxy_info: + author: "Felix Stephen" + description: Role to gather facts + 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: EL + versions: + - "9" + - "8" + - name: Ubuntu + versions: + - jammy + - name: SLES + versions: + - "15SP3" + - "15SP4" + + 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/roles/idrac_gather_facts/molecule/backplane/backplane_assert.yml b/roles/idrac_gather_facts/molecule/backplane/backplane_assert.yml new file mode 100644 index 000000000..ac004b245 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/backplane/backplane_assert.yml @@ -0,0 +1,40 @@ +- name: Get PCIeSSDBackPlanes information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellPCIeSSDBackPlanes/{{ backplane_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: backplane_result + no_log: true + +- name: Set backplane facts + ansible.builtin.set_fact: + api_response: "{{ backplane_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ backplane_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: backplane_data[item]}) }}" + loop: "{{ backplane_data.keys() }}" + when: + - diff_keys | length == 0 + - backplane_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/backplane/converge.yml b/roles/idrac_gather_facts/molecule/backplane/converge.yml new file mode 100644 index 000000000..29cf82a07 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/backplane/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for PCIeSSDBackPlane + hosts: all + connection: local + gather_facts: true + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - PCIeSSDBackPlane + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the PCIeSSDBackPlane component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert backplane dict for length + ansible.builtin.assert: + that: + - "{{ backplane | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: backplane_assert.yml + with_items: "{{ backplane }}" + loop_control: + loop_var: backplane_data + when: backplane | length > 0 diff --git a/roles/idrac_gather_facts/molecule/backplane/molecule.yml b/roles/idrac_gather_facts/molecule/backplane/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/backplane/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/bios/converge.yml b/roles/idrac_gather_facts/molecule/bios/converge.yml new file mode 100644 index 000000000..245f49dfd --- /dev/null +++ b/roles/idrac_gather_facts/molecule/bios/converge.yml @@ -0,0 +1,81 @@ +--- +- name: Converge idrac gather facts for bios + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - BIOS + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the BIOS component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert bios dict for length + ansible.builtin.assert: + that: + - "{{ bios | length > 0 }}" + + - name: Fetching BIOS info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Bios" + validate_certs: false + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: bios_result + no_log: true + + - name: Response filter + ansible.builtin.set_fact: + api_response: + "{{ bios_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.type', '@odata.id', 'SettingsObject', 'Actions', 'AttributeRegistry', 'Description', + 'Id', 'Links', 'Name']) }}" + vars: + jquery: "Oem.Dell.DellSystem" + + - name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ bios.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + + - name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: bios[item]}) }}" + loop: "{{ bios.keys() }}" + when: + - diff_keys | length == 0 + - bios[item] != api_response[item] + - item not in exclude_keys + + - name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/bios/molecule.yml b/roles/idrac_gather_facts/molecule/bios/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/bios/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/controller/controller_assert.yml b/roles/idrac_gather_facts/molecule/controller/controller_assert.yml new file mode 100644 index 000000000..658324708 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/controller/controller_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching Controller info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage/Oem/Dell/DellControllers/{{ controller_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: controller_result + no_log: true + +- name: Set controller facts + ansible.builtin.set_fact: + api_response: "{{ controller_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ controller_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: controller_data[item]}) }}" + loop: "{{ controller_data.keys() }}" + when: + - diff_keys | length == 0 + - controller_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/controller/converge.yml b/roles/idrac_gather_facts/molecule/controller/converge.yml new file mode 100644 index 000000000..679a37125 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/controller/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for controller + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Controller + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: ["Description"] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Controller component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert controller dict for length + ansible.builtin.assert: + that: + - "{{ controller | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: controller_assert.yml + with_items: "{{ controller }}" + loop_control: + loop_var: controller_data + when: controller | length > 0 diff --git a/roles/idrac_gather_facts/molecule/controller/molecule.yml b/roles/idrac_gather_facts/molecule/controller/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/controller/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/cpu/converge.yml b/roles/idrac_gather_facts/molecule/cpu/converge.yml new file mode 100644 index 000000000..ce03e27b5 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/cpu/converge.yml @@ -0,0 +1,45 @@ +--- +- name: Converge idrac_gather_facts for CPU + hosts: all + connection: local + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - CPU + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the CPU component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert cpu dict for length + ansible.builtin.assert: + that: + - "{{ cpu | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: cpu_assert.yml + with_items: "{{ cpu }}" + loop_control: + loop_var: cpu_data + when: cpu | length > 0 diff --git a/roles/idrac_gather_facts/molecule/cpu/cpu_assert.yml b/roles/idrac_gather_facts/molecule/cpu/cpu_assert.yml new file mode 100644 index 000000000..4202748f6 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/cpu/cpu_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching CPU information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Processors/{{ cpu_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: cpu_result + no_log: true + +- name: Set CPU facts + ansible.builtin.set_fact: + api_response: "{{ cpu_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'Assembly', 'Links']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ cpu_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: cpu_data[item]}) }}" + loop: "{{ cpu_data.keys() }}" + when: + - diff_keys | length == 0 + - cpu_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/cpu/molecule.yml b/roles/idrac_gather_facts/molecule/cpu/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/cpu/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/default/converge.yml b/roles/idrac_gather_facts/molecule/default/converge.yml new file mode 100644 index 000000000..79dc86348 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/default/converge.yml @@ -0,0 +1,95 @@ +--- +- name: Converge idrac_gather_facts + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - System + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: ["ServerOS.1.ServerPoweredOnTime"] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the System component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert system dict for length + ansible.builtin.assert: + that: + - "{{ system | length > 0 }}" + + - name: Fetching System info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}" + validate_certs: false + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: system_result + no_log: true + + - name: Fetching operating system info + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Managers/System.Embedded.1/Attributes?$select=ServerOS.*" # verification firmware version 5.00.00 + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: os_result + no_log: true + + - name: Response filter + ansible.builtin.set_fact: + api_response: + "{{ system_result.json | json_query(jquery) | combine(os_result.json.Attributes) | + ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" + vars: + jquery: "Oem.Dell.DellSystem" + + - name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ system.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + + - name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: system[item]}) }}" + loop: "{{ system.keys() }}" + when: + - diff_keys | length == 0 + - system[item] != api_response[item] + - item not in exclude_keys + + - name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/default/molecule.yml b/roles/idrac_gather_facts/molecule/default/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/default/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/enclosure/converge.yml b/roles/idrac_gather_facts/molecule/enclosure/converge.yml new file mode 100644 index 000000000..16fb2ae81 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosure/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for Enclosure + hosts: all + connection: local + gather_facts: true + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Enclosure + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the Enclosure component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert enclosure dict for length + ansible.builtin.assert: + that: + - "{{ enclosure | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: enclosure_assert.yml + with_items: "{{ enclosure }}" + loop_control: + loop_var: enclosure_data + when: enclosure | length > 0 diff --git a/roles/idrac_gather_facts/molecule/enclosure/enclosure_assert.yml b/roles/idrac_gather_facts/molecule/enclosure/enclosure_assert.yml new file mode 100644 index 000000000..a568808e3 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosure/enclosure_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching Enclosure info + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellEnclosures/{{ enclosure_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: enclosure_result + no_log: true + +- name: Set enclosure facts + ansible.builtin.set_fact: + api_response: "{{ enclosure_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type', 'Links', 'Description']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ enclosure_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: enclosure_data[item]}) }}" + loop: "{{ enclosure_data.keys() }}" + when: + - diff_keys | length == 0 + - enclosure_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/enclosure/molecule.yml b/roles/idrac_gather_facts/molecule/enclosure/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosure/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/enclosureemm/converge.yml b/roles/idrac_gather_facts/molecule/enclosureemm/converge.yml new file mode 100644 index 000000000..e2273e7c6 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosureemm/converge.yml @@ -0,0 +1,38 @@ +--- +- name: Converge idrac_gather_facts for EnclosureEMM + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - EnclosureEMM + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the EnclosureEMM component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Call assertion + ansible.builtin.include_tasks: enclosureemm_assert.yml + with_items: "{{ enclosure_emm }}" + loop_control: + loop_var: enclosureemm_data + when: enclosure_emm | length > 0 diff --git a/roles/idrac_gather_facts/molecule/enclosureemm/enclosureemm_assert.yml b/roles/idrac_gather_facts/molecule/enclosureemm/enclosureemm_assert.yml new file mode 100644 index 000000000..b9209dd79 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosureemm/enclosureemm_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching EnclosureEMM info + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellEnclosureEMM/{{ enclosureemm_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: enclosureemm_result + no_log: true + +- name: Set enclosureemm facts + ansible.builtin.set_fact: + api_response: "{{ enclosureemm_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type', 'Description', 'Links']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ enclosureemm_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: enclosureemm_data[item]}) }}" + loop: "{{ enclosureemm_data.keys() }}" + when: + - diff_keys | length == 0 + - enclosureemm_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/enclosureemm/molecule.yml b/roles/idrac_gather_facts/molecule/enclosureemm/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/enclosureemm/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/fan/converge.yml b/roles/idrac_gather_facts/molecule/fan/converge.yml new file mode 100644 index 000000000..5db50e069 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/fan/converge.yml @@ -0,0 +1,38 @@ +--- +- name: Converge idrac_gather_facts for Fan + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Fan + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: ["SpeedPercent"] + + tasks: + - name: Gather Facts for the Fan component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Call assertion + ansible.builtin.include_tasks: fan_assert.yml + with_items: "{{ fan }}" + loop_control: + loop_var: fan_data + when: fan | length > 0 diff --git a/roles/idrac_gather_facts/molecule/fan/fan_assert.yml b/roles/idrac_gather_facts/molecule/fan/fan_assert.yml new file mode 100644 index 000000000..22155fd23 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/fan/fan_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching Fan info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/ThermalSubsystem/Fans/{{ fan_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: fan_result + no_log: true + +- name: Set fan facts + ansible.builtin.set_fact: + api_response: "{{ fan_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ fan_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: fan_data[item]}) }}" + loop: "{{ fan_data.keys() }}" + when: + - diff_keys | length == 0 + - fan_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/fan/molecule.yml b/roles/idrac_gather_facts/molecule/fan/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/fan/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/firmware/converge.yml b/roles/idrac_gather_facts/molecule/firmware/converge.yml new file mode 100644 index 000000000..1d1f45e8a --- /dev/null +++ b/roles/idrac_gather_facts/molecule/firmware/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for Firmware + hosts: all + connection: local + gather_facts: true + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Firmware + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the Firmware component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert firmware dict for length + ansible.builtin.assert: + that: + - "{{ firmware | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: firmware_assert.yml + with_items: "{{ firmware }}" + loop_control: + loop_var: firmware_data + when: firmware | length > 0 diff --git a/roles/idrac_gather_facts/molecule/firmware/firmware_assert.yml b/roles/idrac_gather_facts/molecule/firmware/firmware_assert.yml new file mode 100644 index 000000000..f104efb15 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/firmware/firmware_assert.yml @@ -0,0 +1,41 @@ +- name: Fetching Firmware info + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/UpdateService/FirmwareInventory/{{ firmware_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: firmware_result + no_log: true + +- name: Set firmware facts + ansible.builtin.set_fact: + api_response: "{{ firmware_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type', 'Classifications@odata.count', + 'IdentityInfoType@odata.count', 'IdentityInfoValue@odata.count']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ firmware_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: firmware_data[item]}) }}" + loop: "{{ firmware_data.keys() }}" + when: + - diff_keys | length == 0 + - firmware_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/firmware/molecule.yml b/roles/idrac_gather_facts/molecule/firmware/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/firmware/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/hostnic/converge.yml b/roles/idrac_gather_facts/molecule/hostnic/converge.yml new file mode 100644 index 000000000..60b4810fe --- /dev/null +++ b/roles/idrac_gather_facts/molecule/hostnic/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge idrac_gather_facts for HostNIC + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - HostNIC + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the HostNIC component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert hostnic dict for length + ansible.builtin.assert: + that: + - "{{ hostnic | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: hostnic_assert.yml + with_items: "{{ hostnic }}" + loop_control: + loop_var: hostnic_data + when: hostnic | length > 0 diff --git a/roles/idrac_gather_facts/molecule/hostnic/hostnic_assert.yml b/roles/idrac_gather_facts/molecule/hostnic/hostnic_assert.yml new file mode 100644 index 000000000..3d61df41d --- /dev/null +++ b/roles/idrac_gather_facts/molecule/hostnic/hostnic_assert.yml @@ -0,0 +1,41 @@ +- name: Fetching HostNIC info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/HostInterfaces/{{ hostnic_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: hostnic_result + no_log: true + +- name: Set hostnic facts + ansible.builtin.set_fact: + api_response: "{{ hostnic_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'HostEthernetInterfaces', + 'ManagerEthernetInterface']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ hostnic_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: hostnic_data[item]}) }}" + loop: "{{ hostnic_data.keys() }}" + when: + - diff_keys | length == 0 + - hostnic_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/hostnic/molecule.yml b/roles/idrac_gather_facts/molecule/hostnic/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/hostnic/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/idrac/converge.yml b/roles/idrac_gather_facts/molecule/idrac/converge.yml new file mode 100644 index 000000000..973ad24e3 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/idrac/converge.yml @@ -0,0 +1,87 @@ +--- +- name: Converge idrac_gather_facts for idrac + hosts: all + connection: local + gather_facts: true + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - IDRAC + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: ["ServerOS.1.ServerPoweredOnTime", "SystemInfo.1.SysTime"] + + tasks: + - name: Gather Facts for idrac component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Get System information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/System.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_sys_attr + no_log: true + + - name: Get Manager information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/iDRAC.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_mgr_attr + no_log: true + + - name: Get Lifecycle controller information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/LifecycleController.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_lc_attr + no_log: true + + - name: Set System, Manager, Lifecycle controller facts + ansible.builtin.set_fact: + api_idrac: + api_system_attributes: "{{ response_sys_attr.json.Attributes }}" + api_manager_attributes: "{{ response_mgr_attr.json.Attributes }}" + api_lifecycle_controller_attributes: "{{ response_lc_attr.json.Attributes }}" + + - name: Call assertion For System Attributes + ansible.builtin.include_tasks: system_assert.yml diff --git a/roles/idrac_gather_facts/molecule/idrac/lc_assert.yml b/roles/idrac_gather_facts/molecule/idrac/lc_assert.yml new file mode 100644 index 000000000..df83810d6 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/idrac/lc_assert.yml @@ -0,0 +1,28 @@ +- name: Set the keys diff + ansible.builtin.set_fact: + idrac_lc_attributes: "{{ idrac.lifecycle_controller_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + api_idrac_lc_attributes: "{{ api_idrac.api_lifecycle_controller_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ idrac_lc_attributes.keys() | list | symmetric_difference((api_idrac_lc_attributes.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: idrac_lc_attributes[item]}) }}" + loop: "{{ idrac_lc_attributes.keys() }}" + when: + - diff_keys | length == 0 + - idrac_lc_attributes[item] != api_idrac_lc_attributes[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/idrac/manager_assert.yml b/roles/idrac_gather_facts/molecule/idrac/manager_assert.yml new file mode 100644 index 000000000..6e62062a5 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/idrac/manager_assert.yml @@ -0,0 +1,28 @@ +- name: Set the keys diff + ansible.builtin.set_fact: + idrac_manager_attributes: "{{ idrac.manager_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + api_idrac_manager_attributes: "{{ api_idrac.api_manager_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ idrac_manager_attributes.keys() | list | symmetric_difference((api_idrac_manager_attributes.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: idrac_manager_attributes[item]}) }}" + loop: "{{ idrac_manager_attributes.keys() }}" + when: + - diff_keys | length == 0 + - idrac_manager_attributes[item] != api_idrac_manager_attributes[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/idrac/molecule.yml b/roles/idrac_gather_facts/molecule/idrac/molecule.yml new file mode 100644 index 000000000..38721786c --- /dev/null +++ b/roles/idrac_gather_facts/molecule/idrac/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + # - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/idrac/system_assert.yml b/roles/idrac_gather_facts/molecule/idrac/system_assert.yml new file mode 100644 index 000000000..5376d1d42 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/idrac/system_assert.yml @@ -0,0 +1,28 @@ +- name: Set the keys diff + ansible.builtin.set_fact: + idrac_system_attributes: "{{ idrac.system_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + api_idrac_system_attributes: "{{ api_idrac.api_system_attributes }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ idrac_system_attributes.keys() | list | symmetric_difference((api_idrac_system_attributes.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: idrac_system_attributes[item]}) }}" + loop: "{{ idrac_system_attributes.keys() }}" + when: + - diff_keys | length == 0 + - idrac_system_attributes[item] != api_idrac_system_attributes[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/license/converge.yml b/roles/idrac_gather_facts/molecule/license/converge.yml new file mode 100644 index 000000000..45ca2084e --- /dev/null +++ b/roles/idrac_gather_facts/molecule/license/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge idrac_gather_facts for License + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - License + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the License component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert license dict for length + ansible.builtin.assert: + that: + - "{{ license | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: license_assert.yml + with_items: "{{ license }}" + loop_control: + loop_var: license_data + when: license | length > 0 diff --git a/roles/idrac_gather_facts/molecule/license/license_assert.yml b/roles/idrac_gather_facts/molecule/license/license_assert.yml new file mode 100644 index 000000000..9474ea2e0 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/license/license_assert.yml @@ -0,0 +1,40 @@ +- name: Get license information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/LicenseService/Licenses/{{ license_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: license_result + no_log: true + +- name: Set license facts + ansible.builtin.set_fact: + api_response: "{{ license_result.json | ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ license_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: license_data[item]}) }}" + loop: "{{ license_data.keys() }}" + when: + - diff_keys | length == 0 + - license_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/license/molecule.yml b/roles/idrac_gather_facts/molecule/license/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/license/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/memory/converge.yml b/roles/idrac_gather_facts/molecule/memory/converge.yml new file mode 100644 index 000000000..5d3b62d2a --- /dev/null +++ b/roles/idrac_gather_facts/molecule/memory/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for Memory + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Memory + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Memory component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert memory dict for length + ansible.builtin.assert: + that: + - "{{ memory | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: memory_assert.yml + with_items: "{{ memory }}" + loop_control: + loop_var: memory_data + when: memory | length > 0 diff --git a/roles/idrac_gather_facts/molecule/memory/memory_assert.yml b/roles/idrac_gather_facts/molecule/memory/memory_assert.yml new file mode 100644 index 000000000..2fe1a4b66 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/memory/memory_assert.yml @@ -0,0 +1,41 @@ +- name: Fetching memory info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Memory/{{ memory_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: memory_result + no_log: true + +- name: Set memory facts + ansible.builtin.set_fact: + api_response: "{{ memory_result.json| ansible.utils.remove_keys( + target=['@odata.context', '@odata.id', '@odata.type', 'AllowedSpeedsMHz@odata.count', 'CPUAffinity@odata.count', + 'Processors@odata.count', 'MaxTDPMilliWatts@odata.count', 'OperatingMemoryModes@odata.count']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ memory_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: memory_data[item]}) }}" + loop: "{{ memory_data.keys() }}" + when: + - diff_keys | length == 0 + - memory_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/memory/molecule.yml b/roles/idrac_gather_facts/molecule/memory/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/memory/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/negative/converge.yml b/roles/idrac_gather_facts/molecule/negative/converge.yml new file mode 100644 index 000000000..956f6b3d6 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/negative/converge.yml @@ -0,0 +1,92 @@ +--- +- name: Converge for negative scenarios + hosts: all + gather_facts: false + tasks: + - name: To check for wrong hostname + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "randomHostname" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + ignore_errors: true + ignore_unreachable: true + register: err + + - name: Asserting after performing opeartion with invalid hostname + ansible.builtin.assert: + that: + - connection.status == -1 + + - name: To check for wrong username + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "randomUsername" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: ["Bios"] + ignore_errors: true + ignore_unreachable: true + register: err1 + + - name: Asserting after performing opeartion with invalid username + ansible.builtin.assert: + that: + - connection.status == 401 + + - name: To check for wrong password + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "randomPassword" + validate_certs: false + target: ["Bios"] + ignore_errors: true + ignore_unreachable: true + register: err2 + + - name: Asserting after performing opeartion with invalid password + ansible.builtin.assert: + that: + - connection.status == -1 + + - name: To check for wrong system id + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + computer_system_id: "randomSystemID" + ignore_errors: true + register: err4 + + - name: Asserting after performing operation with invalid system id + ansible.builtin.assert: + that: + - "{{ computer_system_id not in system_ids }}" + + - name: To check for wrong manager id + ansible.builtin.import_role: + name: idrac_gather_facts + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + manager_id: "randomManagerID" + target: ["Firmware"] + ignore_errors: true + register: err5 + + - name: Asserting after performing operation with invalid manager id + ansible.builtin.assert: + that: + - "{{ manager_id not in manager_ids }}" diff --git a/roles/idrac_gather_facts/molecule/negative/molecule.yml b/roles/idrac_gather_facts/molecule/negative/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/negative/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/nic/converge.yml b/roles/idrac_gather_facts/molecule/nic/converge.yml new file mode 100644 index 000000000..8222806c5 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/nic/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for NIC + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - NIC + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the NIC component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert nic dict for length + ansible.builtin.assert: + that: + - "{{ nic | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: nic_assert.yml + with_items: "{{ nic }}" + loop_control: + loop_var: nic_data + when: nic | length > 0 diff --git a/roles/idrac_gather_facts/molecule/nic/molecule.yml b/roles/idrac_gather_facts/molecule/nic/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/nic/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/nic/nic_assert.yml b/roles/idrac_gather_facts/molecule/nic/nic_assert.yml new file mode 100644 index 000000000..4f084675c --- /dev/null +++ b/roles/idrac_gather_facts/molecule/nic/nic_assert.yml @@ -0,0 +1,41 @@ +- name: Get NIC information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/EthernetInterfaces/{{ nic_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: nic_result + no_log: true + +- name: Set nic facts + ansible.builtin.set_fact: + api_response: "{{ nic_result.json| ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'IPv4Addresses@odata.count', 'IPv6AddressPolicyTable@odata.count', + 'IPv6Addresses@odata.count', 'IPv6StaticAddresses@odata.count', 'NameServers@odata.count']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ nic_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: nic_data[item]}) }}" + loop: "{{ nic_data.keys() }}" + when: + - diff_keys | length == 0 + - nic_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/passensor/converge.yml b/roles/idrac_gather_facts/molecule/passensor/converge.yml new file mode 100644 index 000000000..583c72a2b --- /dev/null +++ b/roles/idrac_gather_facts/molecule/passensor/converge.yml @@ -0,0 +1,39 @@ +--- +- name: Converge idrac_gather_facts for Presence and Status Sensor + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - PresenceAndStatusSensor + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Presence and Status Sensor + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Call assertion + ansible.builtin.include_tasks: passensor_assert.yml + with_items: "{{ presence_and_status_sensor }}" + loop_control: + loop_var: passensor_data + when: presence_and_status_sensor | length > 0 diff --git a/roles/idrac_gather_facts/molecule/passensor/molecule.yml b/roles/idrac_gather_facts/molecule/passensor/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/passensor/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/passensor/passensor_assert.yml b/roles/idrac_gather_facts/molecule/passensor/passensor_assert.yml new file mode 100644 index 000000000..f6204cc7d --- /dev/null +++ b/roles/idrac_gather_facts/molecule/passensor/passensor_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching Presence and Status Sensor info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Oem/Dell/DellPresenceAndStatusSensors/{{ passensor_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: passensor_result + +- name: Set presence and status sensor facts + ansible.builtin.set_fact: + api_response: "{{ passensor_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'Assembly', 'Links']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ passensor_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: passensor_data[item]}) }}" + loop: "{{ passensor_data.keys() }}" + when: + - diff_keys | length == 0 + - passensor_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/pciedevice/converge.yml b/roles/idrac_gather_facts/molecule/pciedevice/converge.yml new file mode 100644 index 000000000..197b85715 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/pciedevice/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge idrac_gather_facts for PCIeDevice component + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - PCIeDevice + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the PCIeDevice + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert pcie device dict for length + ansible.builtin.assert: + that: + - "{{ pcie_device | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: pciedevice_assert.yml + with_items: "{{ pcie_device }}" + loop_control: + loop_var: pci_data + when: pcie_device | length > 0 diff --git a/roles/idrac_gather_facts/molecule/pciedevice/molecule.yml b/roles/idrac_gather_facts/molecule/pciedevice/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/pciedevice/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/pciedevice/pciedevice_assert.yml b/roles/idrac_gather_facts/molecule/pciedevice/pciedevice_assert.yml new file mode 100644 index 000000000..aa82edd59 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/pciedevice/pciedevice_assert.yml @@ -0,0 +1,40 @@ +- name: Fetching PCIeDevice info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PCIeDevices/{{ pci_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: pci_result + +- name: Set pcie device facts + ansible.builtin.set_fact: + api_response: "{{ pci_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'Links', '@odata.etag']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ pci_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: pci_data[item]}) }}" + loop: "{{ pci_data.keys() }}" + when: + - diff_keys | length == 0 + - pci_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/physicaldisk/converge.yml b/roles/idrac_gather_facts/molecule/physicaldisk/converge.yml new file mode 100644 index 000000000..144850efe --- /dev/null +++ b/roles/idrac_gather_facts/molecule/physicaldisk/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge idrac_gather_facts for Physical Disk + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - PhysicalDisk + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Physical Disk component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert physical disk dict for length + ansible.builtin.assert: + that: + - "{{ physical_disk | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: physicaldisk_assert.yml + with_items: "{{ physical_disk }}" + loop_control: + loop_var: pd_data + when: physical_disk | length > 0 diff --git a/roles/idrac_gather_facts/molecule/physicaldisk/molecule.yml b/roles/idrac_gather_facts/molecule/physicaldisk/molecule.yml new file mode 100644 index 000000000..38721786c --- /dev/null +++ b/roles/idrac_gather_facts/molecule/physicaldisk/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + # - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/physicaldisk/physicaldisk_assert.yml b/roles/idrac_gather_facts/molecule/physicaldisk/physicaldisk_assert.yml new file mode 100644 index 000000000..f0286cabd --- /dev/null +++ b/roles/idrac_gather_facts/molecule/physicaldisk/physicaldisk_assert.yml @@ -0,0 +1,46 @@ +--- +- name: Get controller id + ansible.builtin.set_fact: + ctrl_id: "{{ pd_data.Id | split(':') | last }}" + +- name: Get Storage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage/{{ ctrl_id }}/Drives/{{ pd_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: disk_result + +- name: Filter Physical Disk data + ansible.builtin.set_fact: + api_response: "{{ disk_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.id', '@odata.type', 'Actions', 'Assembly', 'Links', 'DellDriveSMARTAttributes', + 'DellNVMeSMARTAttributes', 'Operations@odata.count']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ pd_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: pd_data[item]}) }}" + loop: "{{ pd_data.keys() }}" + when: + - diff_keys | length == 0 + - pd_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/powersupply/converge.yml b/roles/idrac_gather_facts/molecule/powersupply/converge.yml new file mode 100644 index 000000000..4798b4b0a --- /dev/null +++ b/roles/idrac_gather_facts/molecule/powersupply/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge idrac_gather_facts for Power Supply + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - PowerSupply + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the Power Supply component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert power supply dict for length + ansible.builtin.assert: + that: + - "{{ power_supply | length > 0 }}" + + - name: Call assertion + ansible.builtin.include_tasks: powersupply_assert.yml + with_items: "{{ power_supply }}" + loop_control: + loop_var: powersupply_data + when: power_supply | length > 0 diff --git a/roles/idrac_gather_facts/molecule/powersupply/molecule.yml b/roles/idrac_gather_facts/molecule/powersupply/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/powersupply/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/powersupply/powersupply_assert.yml b/roles/idrac_gather_facts/molecule/powersupply/powersupply_assert.yml new file mode 100644 index 000000000..b274b5946 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/powersupply/powersupply_assert.yml @@ -0,0 +1,42 @@ +- name: Fetching Power Supply info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PowerSubsystem/PowerSupplies/{{ powersupply_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: powersupply_result + no_log: true + +- name: Set powersupply facts + ansible.builtin.set_fact: + api_response: + "{{ powersupply_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type', 'ActiveInputVoltage@Redfish.Deprecated', 'OperationalStatus@odata.count', + 'RedTypeOfSet@odata.count']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ powersupply_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: powersupply_data[item]}) }}" + loop: "{{ powersupply_data.keys() }}" + when: + - diff_keys | length == 0 + - powersupply_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/sensorsbattery/converge.yml b/roles/idrac_gather_facts/molecule/sensorsbattery/converge.yml new file mode 100644 index 000000000..8ccbe8839 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsbattery/converge.yml @@ -0,0 +1,80 @@ +--- +- name: Converge idrac_gather_facts for Sensors Battery + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Sensors_Battery + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Sensors Battery component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert sensor battery dict for length + ansible.builtin.assert: + that: + - "{{ sensor_battery | length > 0 }}" + + - name: Fetching Sensor Battery info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Oem/Dell/DellSensors/iDRAC.Embedded.1_0x23_SystemBoardCMOSBattery" + validate_certs: false + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: battery_result + + - name: Response filter + ansible.builtin.set_fact: + api_response: + "{{ battery_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type']) }}" + vars: + jquery: "Oem.Dell.DellSystem" + + - name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ sensor_battery.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + + - name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: sensor_battery[item]}) }}" + loop: "{{ sensor_battery.keys() }}" + when: + - diff_keys | length == 0 + - sensor_battery[item] != api_response[item] + - item not in exclude_keys + + - name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/sensorsbattery/molecule.yml b/roles/idrac_gather_facts/molecule/sensorsbattery/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsbattery/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/sensorsintrusion/converge.yml b/roles/idrac_gather_facts/molecule/sensorsintrusion/converge.yml new file mode 100644 index 000000000..22dd12f9e --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsintrusion/converge.yml @@ -0,0 +1,79 @@ +--- +- name: Converge idrac_gather_facts for Sensors Intrusion + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Sensors_Intrusion + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the Sensors Intrusion component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert sensor battery dict for length + ansible.builtin.assert: + that: + - "{{ intrusion_sensor | length > 0 }}" + + - name: Fetching Sensor Battery info + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}?$select=PhysicalSecurity/IntrusionSensor" + validate_certs: false + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: sensorintrusion_result + + - name: Response filter + ansible.builtin.set_fact: + api_response: + "{{ sensorintrusion_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type']) }}" + vars: + jquery: "Oem.Dell.DellSystem" + + - name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ intrusion_sensor.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + + - name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: intrusion_sensor[item]}) }}" + loop: "{{ intrusion_sensor.keys() }}" + when: + - diff_keys | length == 0 + - intrusion_sensor[item] != api_response[item] + - item not in exclude_keys + + - name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/sensorsintrusion/molecule.yml b/roles/idrac_gather_facts/molecule/sensorsintrusion/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsintrusion/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/sensorsvoltage/converge.yml b/roles/idrac_gather_facts/molecule/sensorsvoltage/converge.yml new file mode 100644 index 000000000..3e27256ba --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsvoltage/converge.yml @@ -0,0 +1,65 @@ +--- +- name: Converge idrac_gather_facts for Voltage Sensors + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - Sensors_Voltage + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the voltage sensor component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert power supply dict for length + ansible.builtin.assert: + that: + - "{{ voltages | length > 0 }}" + + - name: Get Sensor Voltage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/Power#/Voltages" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: voltage_result + no_log: true + + - name: Set Sensor Voltage facts + ansible.builtin.set_fact: + "api_response": + "{{ voltage_result.json.Voltages | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type']) }}" + + - name: Call assertion + ansible.builtin.include_tasks: sensorsvoltage_assert.yml + with_items: "{{ voltages }}" + loop_control: + loop_var: sensorsvoltage_data + index_var: index + when: voltages | length > 0 diff --git a/roles/idrac_gather_facts/molecule/sensorsvoltage/molecule.yml b/roles/idrac_gather_facts/molecule/sensorsvoltage/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsvoltage/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/sensorsvoltage/sensorsvoltage_assert.yml b/roles/idrac_gather_facts/molecule/sensorsvoltage/sensorsvoltage_assert.yml new file mode 100644 index 000000000..0e6e2a0da --- /dev/null +++ b/roles/idrac_gather_facts/molecule/sensorsvoltage/sensorsvoltage_assert.yml @@ -0,0 +1,20 @@ +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ sensorsvoltage_data.keys() | list | symmetric_difference((api_response[index].keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: sensorsvoltage_data[item]}) }}" + loop: "{{ sensorsvoltage_data.keys() }}" + when: + - diff_keys | length == 0 + - sensorsvoltage_data[item] != api_response[index][item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/systemmetrics/converge.yml b/roles/idrac_gather_facts/molecule/systemmetrics/converge.yml new file mode 100644 index 000000000..d7705cbd6 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/systemmetrics/converge.yml @@ -0,0 +1,105 @@ +--- +- name: Converge idrac_gather_facts for Power Supply + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - SystemMetrics + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + + tasks: + - name: Gather Facts for the System Metrics component + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Assert power metrics dict for length + ansible.builtin.assert: + that: + - "{{ power_metrics | length > 0 }}" + + - name: Assert thermal metrics dict for length + ansible.builtin.assert: + that: + - "{{ thermal_metrics | length > 0 }}" + + - name: Assert memory metrics dict for length + ansible.builtin.assert: + that: + - "{{ memory_metrics | length > 0 }}" + + - name: Get Thermal Metrics information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/ThermalSubsystem/ThermalMetrics" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_thermal_metrics + no_log: true + + - name: Set Thermal Metrics facts + ansible.builtin.set_fact: + api_thermal_metrics: "{{ response_thermal_metrics.json | + ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri', 'TemperatureReadingsCelsius@odata.count']) }}" + + - name: Call assertion for thermal metrics + ansible.builtin.include_tasks: tmetrics_assert.yml + + - name: Call assertion for memory metrics + ansible.builtin.include_tasks: mmetrics_assert.yml + with_items: "{{ memory_metrics }}" + loop_control: + loop_var: memory_data + when: memory_metrics | length > 0 + + - name: Get Power Supply information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PowerSubsystem/PowerSupplies?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_power_supply + no_log: true + + - name: Set query + ansible.builtin.set_fact: + jq: "[*].Id" + + - name: Get Power Supply Metrics ids + ansible.builtin.set_fact: + psu_ids: "{{ power_result.json.Members | json_query(jq) }}" + + - name: Call assertion for Power metrics + ansible.builtin.include_tasks: psmetrics_assert.yml + with_items: "{{ power_metrics }}" + loop_control: + loop_var: power_data + index_var: index + when: power_metrics | length > 0 diff --git a/roles/idrac_gather_facts/molecule/systemmetrics/mmetrics_assert.yml b/roles/idrac_gather_facts/molecule/systemmetrics/mmetrics_assert.yml new file mode 100644 index 000000000..06abcc3da --- /dev/null +++ b/roles/idrac_gather_facts/molecule/systemmetrics/mmetrics_assert.yml @@ -0,0 +1,38 @@ +- name: Get Memory information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Memory/{{ memory_data.Id }}/MemoryMetrics" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_memory_metrics + no_log: true + +- name: Set Memory Metrics facts + ansible.builtin.set_fact: + api_memory_metrics: "{{ response_memory_metrics.json | ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ memory_data.keys() | list | symmetric_difference((api_memory_metrics.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: memory_data[item]}) }}" + loop: "{{ memory_data.keys() }}" + when: + - diff_keys | length == 0 + - memory_data[item] != api_memory_metrics[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/systemmetrics/molecule.yml b/roles/idrac_gather_facts/molecule/systemmetrics/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/systemmetrics/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/systemmetrics/psmetrics_assert.yml b/roles/idrac_gather_facts/molecule/systemmetrics/psmetrics_assert.yml new file mode 100644 index 000000000..b7de3ce9d --- /dev/null +++ b/roles/idrac_gather_facts/molecule/systemmetrics/psmetrics_assert.yml @@ -0,0 +1,29 @@ +- name: Get Power information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}//PowerSubsystem/PowerSupplies/{{ psu_ids[index] }}/Metrics" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: response_power_metrics + no_log: true + +- name: Set Power Supply Metrics facts + ansible.builtin.set_fact: + api_power_metrics: "{{ response_power_metrics.json | + ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ power_data.keys() | list | symmetric_difference((api_power_metrics.keys() | list)) }}" + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }}" diff --git a/roles/idrac_gather_facts/molecule/systemmetrics/tmetrics_assert.yml b/roles/idrac_gather_facts/molecule/systemmetrics/tmetrics_assert.yml new file mode 100644 index 000000000..25a8229cf --- /dev/null +++ b/roles/idrac_gather_facts/molecule/systemmetrics/tmetrics_assert.yml @@ -0,0 +1,20 @@ +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ thermal_metrics.keys() | list | symmetric_difference((api_thermal_metrics.keys() | list)) }}" + +- name: Set a diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: thermal_metrics[item]}) }}" + loop: "{{ thermal_metrics.keys() }}" + when: + - diff_keys | length == 0 + - thermal_metrics[item] != api_thermal_metrics[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/molecule/virtualdisk/converge.yml b/roles/idrac_gather_facts/molecule/virtualdisk/converge.yml new file mode 100644 index 000000000..34e37b33d --- /dev/null +++ b/roles/idrac_gather_facts/molecule/virtualdisk/converge.yml @@ -0,0 +1,39 @@ +--- +- name: Converge idrac_gather_facts for Virtual Disk + hosts: all + gather_facts: false + vars: + hostname: "{{ lookup('env', 'hostname') }}" + username: "{{ lookup('env', 'username') }}" + password: "{{ lookup('env', 'password') }}" + validate_certs: false + target: + - VirtualDisk + uri_method: "GET" + uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" + uri_body_format: "json" + uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 + uri_return_content: true + diff_data: {} + exclude_keys: [] + api_system: "/redfish/v1/Systems/System.Embedded.1" + + tasks: + - name: Gather Facts for the Virtual Disk + ansible.builtin.include_role: + name: "idrac_gather_facts" + + - name: Call assertion + ansible.builtin.include_tasks: virtualdisk_assert.yml + with_items: "{{ virtual_disk }}" + loop_control: + loop_var: virtualdisk_data + when: virtual_disk | length > 0 diff --git a/roles/idrac_gather_facts/molecule/virtualdisk/molecule.yml b/roles/idrac_gather_facts/molecule/virtualdisk/molecule.yml new file mode 100644 index 000000000..ad4acff37 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/virtualdisk/molecule.yml @@ -0,0 +1,11 @@ +--- +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - converge + - destroy diff --git a/roles/idrac_gather_facts/molecule/virtualdisk/virtualdisk_assert.yml b/roles/idrac_gather_facts/molecule/virtualdisk/virtualdisk_assert.yml new file mode 100644 index 000000000..00fcb0ed9 --- /dev/null +++ b/roles/idrac_gather_facts/molecule/virtualdisk/virtualdisk_assert.yml @@ -0,0 +1,48 @@ +--- +- name: Get controller id + ansible.builtin.set_fact: + ctrl_id: "{{ virtualdisk_data.Id | split(':') | last }}" + +- name: Get Storage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage/{{ ctrl_id }}/Volumes/{{ virtualdisk_data.Id }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + no_log: true + register: virtualdisk_result + +- name: Filter Virtual Disk data + ansible.builtin.set_fact: + api_response: + "{{ virtualdisk_result.json | ansible.utils.remove_keys(target=[ + '@odata.context', '@odata.type', '@odata.id', 'Actions', 'EncryptionTypes@odata.count', + 'Identifiers@odata.count', 'Links', 'Operations@odata.count', 'DellVirtualDisk', + 'DellVirtualDisk@Redfish.Deprecated']) }}" + +- name: Set the keys diff + ansible.builtin.set_fact: + diff_keys: "{{ virtualdisk_data.keys() | list | symmetric_difference((api_response.keys() | list)) }}" + +- name: Set a Diff of dict + ansible.builtin.set_fact: + diff_data: "{{ diff_data | combine({item: virtualdisk_data[item]}) }}" + loop: "{{ virtualdisk_data.keys() }}" + when: + - diff_keys | length == 0 + - virtualdisk_data[item] != api_response[item] + - item not in exclude_keys + +- name: Assert the difference in Keys + ansible.builtin.assert: + that: + - "{{ (diff_keys | length) == 0 }}" + - "{{ (diff_data | length) == 0 }}" + fail_msg: "The response from the role does not match | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" + success_msg: "The response from the role matches | Diff Keys : {{ diff_keys }} Diff Data : {{ diff_data }}" diff --git a/roles/idrac_gather_facts/tasks/get_attributes_info.yml b/roles/idrac_gather_facts/tasks/get_attributes_info.yml new file mode 100644 index 000000000..cc63910d8 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_attributes_info.yml @@ -0,0 +1,55 @@ +--- +- name: Get System information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/System.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: sys_attr + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Manager information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/iDRAC.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: mgr_attr + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Lifecycle controller information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/Oem/Dell/DellAttributes/LifecycleController.Embedded.1" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: lc_attr + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set System, Manager, Lifecycle controller facts + ansible.builtin.set_fact: + idrac: + system_attributes: "{{ sys_attr.json.Attributes }}" + manager_attributes: "{{ mgr_attr.json.Attributes }}" + lifecycle_controller_attributes: "{{ lc_attr.json.Attributes }}" diff --git a/roles/idrac_gather_facts/tasks/get_backplane_info.yml b/roles/idrac_gather_facts/tasks/get_backplane_info.yml new file mode 100644 index 000000000..f2be3cb24 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_backplane_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get PCIeSSDBackPlane information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellPCIeSSDBackPlanes" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: pcie_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set PCIeSSDBackPlane facts + ansible.builtin.set_fact: + backplane: "{{ pcie_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_battery_info.yml b/roles/idrac_gather_facts/tasks/get_battery_info.yml new file mode 100644 index 000000000..2094f4057 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_battery_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get Sensor Battery information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Oem/Dell/DellSensors/iDRAC.Embedded.1_0x23_SystemBoardCMOSBattery" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: battery_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Sensor Battery facts + ansible.builtin.set_fact: + "sensor_battery": + "{{ battery_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_bios_info.yml b/roles/idrac_gather_facts/tasks/get_bios_info.yml new file mode 100644 index 000000000..bccd281bc --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_bios_info.yml @@ -0,0 +1,23 @@ +--- +- name: Get BIOS information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Bios" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: bios_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set BIOS facts + ansible.builtin.set_fact: + bios: + "{{ bios_result.json | ansible.utils.remove_keys(target=['@odata.context', + '@odata.type', '@odata.id', 'SettingsObject', 'Actions', 'AttributeRegistry', 'Description', + 'Id', 'Links', 'Name']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_controller_info.yml b/roles/idrac_gather_facts/tasks/get_controller_info.yml new file mode 100644 index 000000000..47801cc9a --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_controller_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get Controller information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage/Oem/Dell/DellControllers" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: controller_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Controller facts + ansible.builtin.set_fact: + controller: "{{ controller_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_cpu_info.yml b/roles/idrac_gather_facts/tasks/get_cpu_info.yml new file mode 100644 index 000000000..95f4ffffc --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_cpu_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get CPU information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Processors?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: cpu_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set CPU facts + ansible.builtin.set_fact: + cpu: "{{ cpu_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'Assembly', 'Links']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_enclosure_emm_info.yml b/roles/idrac_gather_facts/tasks/get_enclosure_emm_info.yml new file mode 100644 index 000000000..3b22f5601 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_enclosure_emm_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get enclosure EMM information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellEnclosureEMM" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: emm_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set enclosure EMM facts + ansible.builtin.set_fact: + enclosure_emm: "{{ emm_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'Description', 'Links']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_enclosure_info.yml b/roles/idrac_gather_facts/tasks/get_enclosure_info.yml new file mode 100644 index 000000000..5b00ac6fe --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_enclosure_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get enclosure information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis/Oem/Dell/DellEnclosures" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: enclosure_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set enclosure facts + ansible.builtin.set_fact: + enclosure: "{{ enclosure_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'Links', 'Description']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_fan_info.yml b/roles/idrac_gather_facts/tasks/get_fan_info.yml new file mode 100644 index 000000000..8fb31f658 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_fan_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get Fan information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/ThermalSubsystem/Fans?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: fan_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Fan facts + ansible.builtin.set_fact: + fan: "{{ fan_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_firmware_info.yml b/roles/idrac_gather_facts/tasks/get_firmware_info.yml new file mode 100644 index 000000000..68ca650c0 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_firmware_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get Firmware information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/UpdateService/FirmwareInventory?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: firmware_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Firmware facts + ansible.builtin.set_fact: + firmware: + "{{ firmware_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', + 'Classifications@odata.count', 'IdentityInfoType@odata.count', 'IdentityInfoValue@odata.count']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_host_nic_info.yml b/roles/idrac_gather_facts/tasks/get_host_nic_info.yml new file mode 100644 index 000000000..6d91dd90f --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_host_nic_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get HostNIC information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_manager }}/HostInterfaces?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: nic_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set HostNIC facts + ansible.builtin.set_fact: + hostnic: + "{{ nic_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', + 'HostEthernetInterfaces', 'ManagerEthernetInterface']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_intrusion_info.yml b/roles/idrac_gather_facts/tasks/get_intrusion_info.yml new file mode 100644 index 000000000..43f9e45ba --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_intrusion_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get Sensor Battery information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}?$select=PhysicalSecurity/IntrusionSensor" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: intrusion_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Sensor Battery facts + ansible.builtin.set_fact: + "intrusion_sensor": "{{ intrusion_result.json | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_license_info.yml b/roles/idrac_gather_facts/tasks/get_license_info.yml new file mode 100644 index 000000000..bbf3fbf5f --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_license_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get License information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/LicenseService/Licenses?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: license_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set License facts + ansible.builtin.set_fact: + license: "{{ license_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_memory_info.yml b/roles/idrac_gather_facts/tasks/get_memory_info.yml new file mode 100644 index 000000000..f2e8df952 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_memory_info.yml @@ -0,0 +1,23 @@ +--- +- name: Get Memory information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Memory?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: memory_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Memory facts + ansible.builtin.set_fact: + memory: + "{{ memory_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', + 'AllowedSpeedsMHz@odata.count', 'CPUAffinity@odata.count', 'Processors@odata.count', 'MaxTDPMilliWatts@odata.count', + 'OperatingMemoryModes@odata.count']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_metrics_info.yml b/roles/idrac_gather_facts/tasks/get_metrics_info.yml new file mode 100644 index 000000000..1ccf6cab8 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_metrics_info.yml @@ -0,0 +1,108 @@ +--- +- name: Get Power Supply information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PowerSubsystem/PowerSupplies?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: power_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Power Supply Metrics ids + ansible.builtin.set_fact: + power_metrics_ids: "{{ power_result.json.Members | json_query(jquery) }}" + vars: + jquery: "[*].Metrics" + no_log: true + +- name: Get Power Supply Metrics information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ item['@odata.id'] }}" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + loop: "{{ power_metrics_ids }}" + register: power_metrics_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Thermal Metrics information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/ThermalSubsystem/ThermalMetrics" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: thermal_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Memory information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Memory?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: memory_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get Memory Metrics ids + ansible.builtin.set_fact: + memory_metrics_ids: "{{ memory_result.json.Members | json_query(jquery) }}" + vars: + jquery: "[*].Metrics" + no_log: true + +- name: Get Memory Metrics information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ item['@odata.id'] }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + loop: "{{ memory_metrics_ids }}" + register: memory_metrics_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set j query + ansible.builtin.set_fact: + jquery: "[*].json" + +- name: Set Power Supply/Thermal/Memory Metrics facts + ansible.builtin.set_fact: + power_metrics: + "{{ power_metrics_result.results | json_query(jquery) | flatten | + ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri']) }}" + thermal_metrics: + "{{ thermal_result.json | ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri', + 'TemperatureReadingsCelsius@odata.count']) }}" + memory_metrics: + "{{ memory_metrics_result.results | json_query(jquery) | flatten | + ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'DataSourceUri']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_nic_info.yml b/roles/idrac_gather_facts/tasks/get_nic_info.yml new file mode 100644 index 000000000..f80a473dd --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_nic_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get NIC information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/EthernetInterfaces?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: nic_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set NIC facts + ansible.builtin.set_fact: + nic: + "{{ nic_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'IPv4Addresses@odata.count', + 'IPv6AddressPolicyTable@odata.count', 'IPv6Addresses@odata.count', 'IPv6StaticAddresses@odata.count', 'NameServers@odata.count']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_pas_sensor_info.yml b/roles/idrac_gather_facts/tasks/get_pas_sensor_info.yml new file mode 100644 index 000000000..8aaa53aec --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_pas_sensor_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get PresenceAndStatusSensor information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Oem/Dell/DellPresenceAndStatusSensors" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: pas_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set PresenceAndStatusSensor facts + ansible.builtin.set_fact: + "presence_and_status_sensor": + "{{ pas_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'Assembly', + 'Links']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_pcie_device_info.yml b/roles/idrac_gather_facts/tasks/get_pcie_device_info.yml new file mode 100644 index 000000000..2c2d861b6 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_pcie_device_info.yml @@ -0,0 +1,20 @@ +--- +- name: Get PCIeDevice information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PCIeDevices?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: pcie_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set PCIeDevice facts + ansible.builtin.set_fact: + pcie_device: "{{ pcie_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', 'Links', '@odata.etag']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_physical_info.yml b/roles/idrac_gather_facts/tasks/get_physical_info.yml new file mode 100644 index 000000000..05539d80d --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_physical_info.yml @@ -0,0 +1,50 @@ +--- +- name: Get Storage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: disk_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get all storage controller ids. + ansible.builtin.set_fact: + storage_ids_list: "{{ disk_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[*]."@odata.id"' + no_log: true + +- name: Get PhysicalDisk information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ item }}?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + loop: "{{ storage_ids_list }}" + register: result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set query + ansible.builtin.set_fact: + jq: "[*].json.Drives" + +- name: Set Physical Disk facts + ansible.builtin.set_fact: + physical_disk: + "{{ result.results | json_query(jq) | flatten | ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type', + 'Actions', 'Assembly', 'Links', 'DellDriveSMARTAttributes', 'DellNVMeSMARTAttributes', 'Operations@odata.count']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_power_supply_info.yml b/roles/idrac_gather_facts/tasks/get_power_supply_info.yml new file mode 100644 index 000000000..c536e1977 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_power_supply_info.yml @@ -0,0 +1,23 @@ +--- +- name: Get PowerSupply information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/PowerSubsystem/PowerSupplies?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: power_supply_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set PowerSupply facts + ansible.builtin.set_fact: + power_supply: + "{{ power_supply_result.json.Members | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type', 'ActiveInputVoltage@Redfish.Deprecated', 'OperationalStatus@odata.count', + 'RedTypeOfSet@odata.count']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_resource_id.yml b/roles/idrac_gather_facts/tasks/get_resource_id.yml new file mode 100644 index 000000000..ced50f458 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_resource_id.yml @@ -0,0 +1,111 @@ +--- +- name: Get system resource api id + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Systems" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: system_api_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get first System Id from the system response + ansible.builtin.set_fact: + api_system: "{{ system_api_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[0]."@odata.id"' + when: computer_system_id == '' + no_log: true + +- name: Get all system Ids + ansible.builtin.set_fact: + system_ids_list: "{{ system_api_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[*]."@odata.id"' + when: computer_system_id != '' + no_log: true + +- name: Split system ids from the string + ansible.builtin.set_fact: + system_ids: '{{ (system_ids | default([])) + ([item | split("/") | last]) }}' + with_list: "{{ system_ids_list }}" + when: computer_system_id != '' + no_log: true + +- name: Fail when system id is incorrect + ansible.builtin.fail: + msg: "{{ invalid_sys_id_message | format(computer_system_id, (system_ids | join(','))) }}" + when: computer_system_id != "" and not computer_system_id in system_ids + +- name: Get manager resource api id + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Managers" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: manager_api_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get first manager resource id from manager response. + ansible.builtin.set_fact: + api_manager: "{{ manager_api_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[0]."@odata.id"' + when: manager_id == '' + no_log: true + +- name: Get all manager resource ids. + ansible.builtin.set_fact: + manager_ids_list: "{{ manager_api_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[*]."@odata.id"' + when: manager_id != '' + no_log: true + +- name: Split manager ids from the string + ansible.builtin.set_fact: + manager_ids: '{{ (manager_ids | default([])) + ([item | split("/") | last]) }}' + with_list: "{{ manager_ids_list }}" + when: manager_id != '' + no_log: true + +- name: Fail when manager id is incorrect + ansible.builtin.fail: + msg: "{{ invalid_manager_id_message | format(manager_id, (manager_ids | join(','))) }}" + when: manager_id != "" and not manager_id in manager_ids + +- name: Get chassis resource api id + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Chassis" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: chassis_api_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get first chassis resource id from manager response. + ansible.builtin.set_fact: + api_chassis: "{{ chassis_api_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[0]."@odata.id"' + no_log: true diff --git a/roles/idrac_gather_facts/tasks/get_system_info.yml b/roles/idrac_gather_facts/tasks/get_system_info.yml new file mode 100644 index 000000000..71a7aa203 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_system_info.yml @@ -0,0 +1,40 @@ +--- +- name: Get system information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: system_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get operating system information. + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Managers/System.Embedded.1/Attributes?$select=ServerOS.*" # verification firmware version 5.00.00 + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: os_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set system facts + ansible.builtin.set_fact: + system: + "{{ system_result.json | json_query(jquery) | combine(os_result.json.Attributes) | + ansible.utils.remove_keys(target=['@odata.context', '@odata.id', '@odata.type']) }}" + vars: + jquery: "Oem.Dell.DellSystem" diff --git a/roles/idrac_gather_facts/tasks/get_virtual_disk_info.yml b/roles/idrac_gather_facts/tasks/get_virtual_disk_info.yml new file mode 100644 index 000000000..08e220e19 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_virtual_disk_info.yml @@ -0,0 +1,50 @@ +--- +- name: Get Storage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_system }}/Storage" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: virtual_disk_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Get all storage controller ids. + ansible.builtin.set_fact: + storage_ids_list: "{{ virtual_disk_result.json | default('') | json_query(jquery) }}" + vars: + jquery: 'Members[*]."@odata.id"' + no_log: true + +- name: Get Virtual Disk information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ item }}/Volumes?$expand=*($levels=1)" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + loop: "{{ storage_ids_list }}" + register: result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set query + ansible.builtin.set_fact: + jq: "[*].json.Drives" + +- name: Set Virtual Disk facts + ansible.builtin.set_fact: + virtual_disk: + "{{ result.results | json_query(jq) | flatten | ansible.utils.remove_keys(target=['@odata.context', '@odata.type', '@odata.id', 'Actions', + 'EncryptionTypes@odata.count', 'Identifiers@odata.count', 'Links', 'Operations@odata.count', 'DellVirtualDisk', 'DellVirtualDisk@Redfish.Deprecated']) }}" diff --git a/roles/idrac_gather_facts/tasks/get_voltage_info.yml b/roles/idrac_gather_facts/tasks/get_voltage_info.yml new file mode 100644 index 000000000..bf2cee8d0 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/get_voltage_info.yml @@ -0,0 +1,22 @@ +--- +- name: Get Sensor Voltage information. + ansible.builtin.uri: + url: "https://{{ hostname }}{{ api_chassis }}/Power#/Voltages" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: voltage_result + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Set Sensor Voltage facts + ansible.builtin.set_fact: + "voltages": + "{{ voltage_result.json.Voltages | ansible.utils.remove_keys(target=['@odata.context', + '@odata.id', '@odata.type']) }}" diff --git a/roles/idrac_gather_facts/tasks/main.yml b/roles/idrac_gather_facts/tasks/main.yml new file mode 100644 index 000000000..009edc579 --- /dev/null +++ b/roles/idrac_gather_facts/tasks/main.yml @@ -0,0 +1,149 @@ +--- +- name: Set default facts + ansible.builtin.set_fact: + idrac: {} + system: {} + bios: {} + controller: [] + cpu: [] + enclosure: [] + enclosure_emm: [] + fan: [] + firmware: [] + hostnic: [] + license: [] + memory: [] + nic: [] + backplane: [] + power_supply: [] + presence_and_status_sensor: [] + sensor_battery: {} + intrusion_sensor: {} + voltages: [] + virtual_disk: [] + pcie_device: {} + physical_disk: [] + power_metrics: [] + thermal_metrics: [] + memory_metrics: [] + +- name: Get connection + ansible.builtin.uri: + url: "https://{{ hostname }}/redfish/v1/Systems" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + method: "{{ uri_method }}" + user: "{{ username }}" + password: "{{ password }}" + headers: "{{ uri_headers }}" + body_format: "{{ uri_body_format }}" + status_code: "{{ uri_status_code }}" + return_content: "{{ uri_return_content }}" + register: connection + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + no_log: true + +- name: Fail when hostname or certificate is incorrect or invalid. + ansible.builtin.fail: + msg: "{{ connection.msg }}" + when: connection.status == -1 + +- name: Fail when credentials are incorrect or invalid. + ansible.builtin.fail: + msg: "The authentication credentials included with this request are missing or invalid." + when: connection.status == 401 + +- name: Get System, Manager and Chassis resource id. + ansible.builtin.include_tasks: get_resource_id.yml + +- name: Gather System, Manager, Lifecycle controller facts. + ansible.builtin.include_tasks: get_attributes_info.yml + when: target is defined and "IDRAC" in target + +- name: Gather System facts. + ansible.builtin.include_tasks: get_system_info.yml + when: target is defined and "System" in target + +- name: Gather BIOS facts. + ansible.builtin.include_tasks: get_bios_info.yml + when: target is defined and "BIOS" in target + +- name: Gather Controller facts. + ansible.builtin.include_tasks: get_controller_info.yml + when: target is defined and "Controller" in target + +- name: Gather CPU facts. + ansible.builtin.include_tasks: get_cpu_info.yml + when: target is defined and "CPU" in target + +- name: Gather Enclosure facts. + ansible.builtin.include_tasks: get_enclosure_info.yml + when: target is defined and "Enclosure" in target + +- name: Gather Enclosure EMM facts. + ansible.builtin.include_tasks: get_enclosure_emm_info.yml + when: target is defined and "EnclosureEMM" in target + +- name: Gather Fan facts. + ansible.builtin.include_tasks: get_fan_info.yml + when: target is defined and "Fan" in target + +- name: Gather Firmware facts. + ansible.builtin.include_tasks: get_firmware_info.yml + when: target is defined and "Firmware" in target + +- name: Gather HostNIC facts. + ansible.builtin.include_tasks: get_host_nic_info.yml + when: target is defined and "HostNIC" in target + +- name: Gather License facts. + ansible.builtin.include_tasks: get_license_info.yml + when: target is defined and "License" in target + +- name: Gather Memory facts. + ansible.builtin.include_tasks: get_memory_info.yml + when: target is defined and "Memory" in target + +- name: Gather NIC facts. + ansible.builtin.include_tasks: get_nic_info.yml + when: target is defined and "NIC" in target + +- name: Gather PCIeSSDBackPlane facts. + ansible.builtin.include_tasks: get_backplane_info.yml + when: target is defined and "PCIeSSDBackPlane" in target + +- name: Gather PowerSupply facts. + ansible.builtin.include_tasks: get_power_supply_info.yml + when: target is defined and "PowerSupply" in target + +- name: Gather PresenceAndStatusSensor facts. + ansible.builtin.include_tasks: get_pas_sensor_info.yml + when: target is defined and "PresenceAndStatusSensor" in target + +- name: Gather Sensors Battery facts. + ansible.builtin.include_tasks: get_battery_info.yml + when: target is defined and "Sensors_Battery" in target + +- name: Gather Sensors Intrusion facts. + ansible.builtin.include_tasks: get_intrusion_info.yml + when: target is defined and "Sensors_Intrusion" in target + +- name: Gather Sensors Voltage facts. + ansible.builtin.include_tasks: get_voltage_info.yml + when: target is defined and "Sensors_Voltage" in target + +- name: Gather VirtualDisk facts. + ansible.builtin.include_tasks: get_virtual_disk_info.yml + when: target is defined and "VirtualDisk" in target + +- name: Gather PCIeDevice facts. + ansible.builtin.include_tasks: get_pcie_device_info.yml + when: target is defined and "PCIeDevice" in target + +- name: Gather PhysicalDisk facts. + ansible.builtin.include_tasks: get_physical_info.yml + when: target is defined and "PhysicalDisk" in target + +- name: Gather SystemMetrics facts. + ansible.builtin.include_tasks: get_metrics_info.yml + when: target is defined and "SystemMetrics" in target diff --git a/roles/idrac_gather_facts/tests/inventory b/roles/idrac_gather_facts/tests/inventory new file mode 100644 index 000000000..878877b07 --- /dev/null +++ b/roles/idrac_gather_facts/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/idrac_gather_facts/tests/test.yml b/roles/idrac_gather_facts/tests/test.yml new file mode 100644 index 000000000..f9e315314 --- /dev/null +++ b/roles/idrac_gather_facts/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: Call Role Gather Facts + hosts: localhost + remote_user: root + roles: + - idrac_gather_facts diff --git a/roles/idrac_gather_facts/vars/main.yml b/roles/idrac_gather_facts/vars/main.yml new file mode 100644 index 000000000..1da5ac999 --- /dev/null +++ b/roles/idrac_gather_facts/vars/main.yml @@ -0,0 +1,18 @@ +--- +# vars file for idrac_gather_facts +invalid_sys_id_message: "Invalid computer system id : %s, valid values are %s" +invalid_manager_id_message: "Invalid computer manager id : %s, valid values are %s" + +uri_method: "GET" +uri_headers: + Accept: "application/json" + Content-Type: "application/json" + OData-Version: "4.0" +uri_body_format: "json" +uri_status_code: + - 200 + - 400 + - 401 + - 404 + - -1 +uri_return_content: true diff --git a/roles/idrac_import_server_config_profile/.yamllint b/roles/idrac_import_server_config_profile/.yamllint new file mode 100644 index 000000000..882767605 --- /dev/null +++ b/roles/idrac_import_server_config_profile/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/idrac_import_server_config_profile/README.md b/roles/idrac_import_server_config_profile/README.md new file mode 100644 index 000000000..f1ff16f5f --- /dev/null +++ b/roles/idrac_import_server_config_profile/README.md @@ -0,0 +1,394 @@ +# idrac_import_server_config_profile + +Role to import the Server Configuration Profile (SCP) from the iDRAC to a network share (CIFS, NFS, HTTP, HTTPS) or a local path. + +## 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameRequiredDefault ValueChoicesTypeDescription
hostnametruestriDRAC IP Address
usernametruestriDRAC username
passwordtruestriDRAC user password.
https_portfalse443intiDRAC port.
validate_certsfalsetruebool- If C(false), the SSL certificates will not be validated.
- Configure C(false) only on personally controlled sites where self-signed certificates are used.
ca_pathfalsepathThe Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
https_timeoutfalse30int The HTTPS socket level timeout in seconds.
share_parametersfalsedictNetwork share parameters.
     share_namefalsestr- Network share or local path.
- CIFS, NFS, HTTP, and HTTPS network share types are supported.
     scp_filefalsestr- Name of the server configuration profile (SCP) file.
- The default format `idrac_ip_YYMMDD_HHMMSS_scp` is used if this option is not specified.
- I(export_format) is used if the valid extension file is not provided.
     share_userfalsestrNetwork 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..
     share_passwordfalsestrNetwork share user password. This option is mandatory for CIFS Network Share.
     proxy_supportfalsefalsebool- Proxy to be enabled or disabled.
- I(proxy_support) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     proxy_typefalsehttphttp, socks4str- C(http) to select HTTP type proxy.
- C(socks4) to select SOCKS4 type proxy.
- I(proxy_type) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     proxy_serverfalsestr - I(proxy_server) is required when I(share_name) is of type HTTPS or HTTP and I(proxy_support) is C(true).
- I(proxy_server) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     proxy_portfalse80str- Proxy port to authenticate.
- I(proxy_port) is required when I(share_name) is of type HTTPS or HTTP and I(proxy_support) is C(true).
- I(proxy_port) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     proxy_usernamefalsestr- Proxy username to authenticate.
- I(proxy_username) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     proxy_passwordfalsestr- Proxy password to authenticate.
- I(proxy_password) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9.
     ignore_certificate_warningfalseignoreignore, showerrorstr- If C(ignore), it ignores the certificate warnings.
- If C(showerror), it shows the certificate warnings.
+ - I(ignore_certificate_warning) is considered only when I(share_name) is of type HTTPS and is supported only on iDRAC9.
targetfalse['ALL']'ALL', 'IDRAC', 'BIOS', 'NIC', 'RAID'str- If C(ALL), this module exports or imports all components configurations from SCP file.
- If C(IDRAC), this module exports or imports iDRAC configuration from SCP file.
- If C(BIOS), this module exports or imports BIOS configuration from SCP file.
- If C(NIC), this module exports or imports NIC configuration from SCP file.
- If C(RAID), this module exports or imports RAID configuration from SCP file.
- When I(command) is C(export) or C(import) I(target) with multiple components is supported only on iDRAC9 with firmware 6.10.00.00 and above.
import_bufferfalse'Enabled', 'Disabled'str - SCP content buffer.
+ - This is mutually exclusive with share_parameters.scp_file. +
end_host_power_statefalse'On''On', 'Off'str Host power state after import of server configuration profile.
shutdown_typefalse'Graceful''Graceful', 'Forced', 'NoReboot'str Server shutdown type.
+ +## Fact variables + + + + + + + + + + + + + + + + +
NameSampleDescription
idrac_import_server_config_profile_out{ + "changed": false, + "msg": "Successfully imported the Server Configuration Profile.", + "scp_status": { + "CompletionTime": "2023-02-21T04:12:37", + "Description": "Job Instance", + "EndTime": null, + "Id": "JID_774927528227", + "JobState": "Completed", + "JobType": "ImportConfiguration", + "Message": "No changes were applied since the current component configuration matched the requested configuration.", + "MessageArgs": [], + "MessageId": "IDRAC.2.8.SYS069", + "Name": "Configure: Import Server Configuration Profile", + "PercentComplete": 100, + "StartTime": "TIME_NOW", + "TargetSettingsURI": null, + "TaskStatus": "OK", + "file": ".\\192.1.2.1_2023221_5549_scp.xml", + "retval": true + } +}Module output of the Server Configuration Job
+ +## Examples +----- + +``` +- name: Importing SCP from local path with all components + ansible.builtin.import_role: + name: idrac_import_server_config_profile + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + share_parameters: + share_name: "/root/tmp" + scp_file: "file.xml" +``` +``` +- name: Importing SCP from NFS with iDRAC components + ansible.builtin.import_role: + name: idrac_import_server_config_profile + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['IDRAC'] + share_parameters: + share_name: "191.2.1.1:/nfs" + scp_file: "file.json" +``` +``` +- name: Importing SCP from CIFS with BIOS components + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['BIOS'] + share_parameters: + share_name: "\\\\191.1.1.1\\cifs" + share_user: "username" + share_password: "password" + scp_file: "file.xml" +``` +``` +- name: Importing SCP from HTTPS with RAID components + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['RAID'] + share_parameters: + share_name: "https://192.1.1.1/share" + share_user: "username" + share_password: "password" + scp_file: "filename.json" +``` +``` +- name: "Importing SCP from HTTP with NIC components" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['NIC'] + share_parameters: + share_name: "http://192.1.1.1/share" + share_user: "username" + share_password: "password" + scp_file: "filename.xml" +``` +``` +- name: "Importing SCP using import buffer with NIC components" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['NIC'] + import_buffer: " Disabled" +``` +``` +- name: "Importing SCP from HTTP with NIC components using proxy" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + target: ['NIC'] + share_parameters: + share_name: "http://192.1.1.1/share" + share_user: "username" + share_password: "password" + scp_file: "filename.xml" + proxy_support: true + proxy_server: 192.168.0.6 + proxy_port: 8080 + proxy_type: socks4 +``` +``` +- name: Import SCP + hosts: idrac + connection: local + roles: + - role: idrac_import_server_config_profile +``` + +## Author Information +------------------ + +Dell Technologies
+Abhishek Sinha (Abhishek.Sinha10@Dell.com) 2023 diff --git a/roles/idrac_import_server_config_profile/defaults/main.yml b/roles/idrac_import_server_config_profile/defaults/main.yml new file mode 100644 index 000000000..79e251f31 --- /dev/null +++ b/roles/idrac_import_server_config_profile/defaults/main.yml @@ -0,0 +1,15 @@ +--- +# defaults file for idrac_import_server_config_profile + +https_port: 443 +validate_certs: true +https_timeout: 30 +end_host_power_state: 'On' +shutdown_type: Graceful +share_parameters: + proxy_support: false + proxy_type: http + proxy_port: "80" + ignore_certificate_warning: ignore +target: + - 'ALL' diff --git a/roles/idrac_import_server_config_profile/handlers/main.yml b/roles/idrac_import_server_config_profile/handlers/main.yml new file mode 100644 index 000000000..6a96ab10f --- /dev/null +++ b/roles/idrac_import_server_config_profile/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for idrac_import_server_config_profile diff --git a/roles/idrac_import_server_config_profile/meta/argument_specs.yml b/roles/idrac_import_server_config_profile/meta/argument_specs.yml new file mode 100644 index 000000000..be94f4225 --- /dev/null +++ b/roles/idrac_import_server_config_profile/meta/argument_specs.yml @@ -0,0 +1,138 @@ +--- +argument_specs: + main: + version_added: "7.4.0" + short_description: Import iDRAC Server Configuration Profile (SCP). + description: The role performs Import operation of Server Configuration Profile. + options: + hostname: + required: true + type: str + description: iDRAC IP Address. + username: + required: true + type: str + description: iDRAC username. + password: + required: true + 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. + 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 + https_timeout: + description: The socket level timeout in seconds. + type: int + default: 30 + share_parameters: + type: dict + options: + share_name: + description: + - Network share or local path. + - CIFS, NFS, HTTP, and HTTPS network share types are supported. + - I(share_name) is mutually exclusive with I(import_buffer). + type: str + scp_file: + description: + - Name of the server configuration profile (SCP) file. + - This option is mandatory if I(command) is C(import). + - The default format _YYMMDD_HHMMSS_scp is used if this option is not specified for C(import). + - I(export_format) is used if the valid extension file is not provided for C(export). + type: str + 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 + proxy_support: + description: + - Proxy to be enabled or disabled. + - I(proxy_support) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: bool + default: false + proxy_type: + description: + - C(http) to select HTTP type proxy. + - C(socks4) to select SOCKS4 type proxy. + - I(proxy_type) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: str + choices: [http, socks4] + default: http + proxy_server: + description: + - I(proxy_server) is required when I(share_name) is of type HTTPS or HTTP and I(proxy_support) is C(true). + - I(proxy_server) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: str + proxy_port: + description: + - Proxy port to authenticate. + - I(proxy_port) is required when I(share_name) is of type HTTPS or HTTP and I(proxy_support) is C(true). + - I(proxy_port) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: int + default: 80 + proxy_username: + description: + - Proxy username to authenticate. + - I(proxy_username) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: str + proxy_password: + description: + - Proxy password to authenticate. + - I(proxy_password) is considered only when I(share_name) is of type HTTP or HTTPS and is supported only on iDRAC9. + type: str + ignore_certificate_warning: + description: + - If C(ignore), it ignores the certificate warnings. + - If C(showerror), it shows the certificate warnings. + - I(ignore_certificate_warning) is considered only when I(share_name) is of type HTTPS and is + supported only on iDRAC9. + type: str + choices: [ignore, showerror] + default: ignore + target: + description: + - If C(ALL), this module exports or imports all components configurations from SCP file. + - If C(IDRAC), this module exports or imports iDRAC configuration from SCP file. + - If C(BIOS), this module exports or imports BIOS configuration from SCP file. + - If C(NIC), this module exports or imports NIC configuration from SCP file. + - If C(RAID), this module exports or imports RAID configuration from SCP file. + choices: ['ALL', 'IDRAC', 'BIOS', 'NIC', 'RAID'] + default: ['ALL'] + type: list + import_buffer: + description: + - Used to import the buffer input of xml or json into the iDRAC. + - This option is applicable when I(command) is C(import) and C(preview). + - I(import_buffer) is mutually exclusive with I(share_name). + type: str + shutdown_type: + description: + - This option is applicable for C(import) command. + - If C(Graceful), the job gracefully shuts down the operating system and turns off the server. + - If C(Forced), it forcefully shuts down the server. + - If C(NoReboot), the job that applies the SCP will pause until you manually reboot the server. + type: str + choices: ['Graceful', 'Forced', 'NoReboot'] + default: 'Graceful' + end_host_power_state: + description: + - This option is applicable for C(import) command. + - If C(On), End host power state is on. + - If C(Off), End host power state is off. + type: str + choices: ['On', 'Off'] + default: 'On' diff --git a/roles/idrac_import_server_config_profile/meta/main.yml b/roles/idrac_import_server_config_profile/meta/main.yml new file mode 100644 index 000000000..c4ba1bd9c --- /dev/null +++ b/roles/idrac_import_server_config_profile/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: Abhishek Sinha ('Abhishek-Dell') + description: The role performs import operation of Server Configuration Profile. + 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: EL + versions: + - "9" + - "8" + - name: Ubuntu + versions: + - jammy + - name: SLES + versions: + - "15SP3" + - "15SP4" + + 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/roles/idrac_import_server_config_profile/molecule/cifs_share/converge.yml b/roles/idrac_import_server_config_profile/molecule/cifs_share/converge.yml new file mode 100644 index 000000000..29ff66275 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/cifs_share/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: "Importing SCP from CIFS with ALL components" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + share_parameters: + share_name: "{{ lookup('env', 'CIFS_URL') }}" + share_user: "{{ lookup('env', 'CIFS_USERNAME') }}" + share_password: "{{ lookup('env', 'CIFS_PASSWORD') }}" + scp_file: "{{ lookup('env', 'cifs_filename') }}" + + - name: Verifying Import SCP from CIFS with ALL components + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "Successfully imported and applied Server Configuration Profile." + when: not ansible_check_mode + tags: molecule-idempotence-notest + + - name: Verifying Import SCP from CIFS with ALL components in check mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Verifying Import SCP from CIFS with ALL components in idempotence mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "No changes were applied since the + current component configuration matched the requested configuration." + when: not ansible_check_mode and not idrac_import_server_config_profile_out.changed diff --git a/roles/idrac_import_server_config_profile/molecule/cifs_share/molecule.yml b/roles/idrac_import_server_config_profile/molecule/cifs_share/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_import_server_config_profile/molecule/cifs_share/prepare.yml b/roles/idrac_import_server_config_profile/molecule/cifs_share/prepare.yml new file mode 100644 index 000000000..5fadc24b5 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/cifs_share/prepare.yml @@ -0,0 +1,7 @@ +--- +- name: Cleanup + hosts: all + gather_facts: false + tasks: + - name: Cleanup config + ansible.builtin.include_tasks: ../resources/tests/prepare.yml diff --git a/roles/idrac_import_server_config_profile/molecule/default/converge.yml b/roles/idrac_import_server_config_profile/molecule/default/converge.yml new file mode 100644 index 000000000..b1d053a6f --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/default/converge.yml @@ -0,0 +1,300 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: "Importing SCP without share_name" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + target: ['IDRAC'] + share_parameters: + share_user: "{{ lookup('env', 'USERNAME') }}" + share_password: "{{ lookup('env', 'PASSWORD') }}" + scp_file: "{{ lookup('env', 'http_filename') }}" + ignore_errors: true + register: import_status + + - name: "Verifying Import SCP without share_name" + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "argument of type 'NoneType' is not iterable" + + - name: "Importing SCP without scp_file" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + target: ['IDRAC'] + share_parameters: + share_name: "{{ lookup('env', 'HTTP_URL') }}" + share_user: "{{ lookup('env', 'USERNAME') }}" + share_password: "{{ lookup('env', 'PASSWORD') }}" + ignore_errors: true + register: import_status + + - name: "Verifying Import SCP without scp_file" + ansible.builtin.assert: + that: + - "'HTTP Error 400' in '{{ idrac_import_server_config_profile_out.msg }}'" + + - name: "Importing SCP from CIFS with ALL components with invalid file" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + share_parameters: + share_name: "{{ lookup('env', 'CIFS_URL') }}" + share_user: "{{ lookup('env', 'CIFS_USERNAME') }}" + share_password: "{{ lookup('env', 'CIFS_PASSWORD') }}" + scp_file: "invalid_file.xml" + ignore_errors: true + register: import_status + + - name: "Verifying Import SCP from CIFS with ALL components with invalid file" + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Failed to import scp." + + - name: Wait for 15 seconds + ansible.builtin.pause: + seconds: 15 + + - name: "Importing SCP from CIFS with ALL components with invalid share" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + share_parameters: + share_name: "192.168.0.1:/cifsshare" + share_user: "{{ lookup('env', 'CIFS_USERNAME') }}" + share_password: "{{ lookup('env', 'CIFS_PASSWORD') }}" + scp_file: "{{ lookup('env', 'cifs_filename') }}" + ignore_errors: true + register: import_status + + - name: "Verifying Import SCP from CIFS with ALL components with invalid share" + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Failed to import scp." + + - name: "Importing SCP with invalid hostname" + ansible.builtin.import_role: + name: "idrac_import_server_config_profile" + vars: + hostname: "randomHostname" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + share_parameters: + share_name: "{{ lookup('env', 'CIFS_URL') }}" + share_user: "{{ lookup('env', 'CIFS_USERNAME') }}" + share_password: "{{ lookup('env', 'CIFS_PASSWORD') }}" + scp_file: "{{ lookup('env', 'cifs_filename') }}" + ignore_errors: true + ignore_unreachable: true + register: import_status + + - name: "Verifying Import SCP with invalid hostname" + ansible.builtin.assert: + that: + - "'CST6CDT + ' + when: not ansible_check_mode + + - name: Verifying Import SCP from import buffer with IDRAC components in normal mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "Successfully imported and applied Server Configuration Profile." + when: not ansible_check_mode + tags: molecule-idempotence-notest + + - name: Verifying Import SCP from import buffer with IDRAC components in idempotence mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "No changes were applied since the + current component configuration matched the requested configuration." + when: not ansible_check_mode and not idrac_import_server_config_profile_out.changed diff --git a/roles/idrac_import_server_config_profile/molecule/import_buffer_xml/molecule.yml b/roles/idrac_import_server_config_profile/molecule/import_buffer_xml/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_import_server_config_profile/molecule/import_buffer_xml/prepare.yml b/roles/idrac_import_server_config_profile/molecule/import_buffer_xml/prepare.yml new file mode 100644 index 000000000..5fadc24b5 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/import_buffer_xml/prepare.yml @@ -0,0 +1,7 @@ +--- +- name: Cleanup + hosts: all + gather_facts: false + tasks: + - name: Cleanup config + ansible.builtin.include_tasks: ../resources/tests/prepare.yml diff --git a/roles/idrac_import_server_config_profile/molecule/import_multiple_target/converge.yml b/roles/idrac_import_server_config_profile/molecule/import_multiple_target/converge.yml new file mode 100644 index 000000000..860e63b52 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/import_multiple_target/converge.yml @@ -0,0 +1,41 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + + - name: "Importing SCP from NFS with multiple components" + ansible.builtin.import_role: + name: idrac_import_server_config_profile + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + target: + - 'NIC' + - 'IDRAC' + share_parameters: + share_name: "{{ lookup('env', 'NFS_URL') }}" + scp_file: "{{ lookup('env', 'nfs_filename') }}" + shutdown_type: 'Forced' + end_host_power_state: 'On' + when: not ansible_check_mode + + - name: Verifying Import SCP from NFS with multiple components in normal mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "Successfully imported and applied Server Configuration Profile." + when: not ansible_check_mode + tags: molecule-idempotence-notest + + - name: Verifying Import SCP from NFS with multiple components in idempotence mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "No changes were applied since the + current component configuration matched the requested configuration." + when: not ansible_check_mode and not idrac_import_server_config_profile_out.changed diff --git a/roles/idrac_import_server_config_profile/molecule/import_multiple_target/molecule.yml b/roles/idrac_import_server_config_profile/molecule/import_multiple_target/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_import_server_config_profile/molecule/import_multiple_target/prepare.yml b/roles/idrac_import_server_config_profile/molecule/import_multiple_target/prepare.yml new file mode 100644 index 000000000..5fadc24b5 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/import_multiple_target/prepare.yml @@ -0,0 +1,7 @@ +--- +- name: Cleanup + hosts: all + gather_facts: false + tasks: + - name: Cleanup config + ansible.builtin.include_tasks: ../resources/tests/prepare.yml diff --git a/roles/idrac_import_server_config_profile/molecule/nfs_share/converge.yml b/roles/idrac_import_server_config_profile/molecule/nfs_share/converge.yml new file mode 100644 index 000000000..bb839b38b --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/nfs_share/converge.yml @@ -0,0 +1,38 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + + - name: "Importing SCP from NFS" + ansible.builtin.import_role: + name: idrac_import_server_config_profile + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + share_parameters: + share_name: "{{ lookup('env', 'NFS_URL') }}" + scp_file: "{{ lookup('env', 'nfs_filename') }}" + shutdown_type: 'Forced' + end_host_power_state: 'On' + when: not ansible_check_mode + + - name: Verifying Import SCP from NFS with in normal mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "Successfully imported and applied Server Configuration Profile." + when: not ansible_check_mode + tags: molecule-idempotence-notest + + - name: Verifying Import SCP from NFS in idempotence mode + ansible.builtin.assert: + that: + - idrac_import_server_config_profile_out.msg == "Successfully imported the Server Configuration Profile." + - idrac_import_server_config_profile_out.scp_status.JobState == "Completed" + - idrac_import_server_config_profile_out.scp_status.Message == "No changes were applied since the + current component configuration matched the requested configuration." + when: not ansible_check_mode and not idrac_import_server_config_profile_out.changed diff --git a/roles/idrac_import_server_config_profile/molecule/nfs_share/molecule.yml b/roles/idrac_import_server_config_profile/molecule/nfs_share/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_import_server_config_profile/molecule/nfs_share/prepare.yml b/roles/idrac_import_server_config_profile/molecule/nfs_share/prepare.yml new file mode 100644 index 000000000..5fadc24b5 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/nfs_share/prepare.yml @@ -0,0 +1,7 @@ +--- +- name: Cleanup + hosts: all + gather_facts: false + tasks: + - name: Cleanup config + ansible.builtin.include_tasks: ../resources/tests/prepare.yml diff --git a/roles/idrac_import_server_config_profile/molecule/resources/tests/prepare.yml b/roles/idrac_import_server_config_profile/molecule/resources/tests/prepare.yml new file mode 100644 index 000000000..aa9fd74c5 --- /dev/null +++ b/roles/idrac_import_server_config_profile/molecule/resources/tests/prepare.yml @@ -0,0 +1,18 @@ +--- +- name: "Cleanup config" + ansible.builtin.import_role: + name: idrac_import_server_config_profile + vars: + hostname: "{{ lookup('env', 'HOSTNAME') }}" + username: "{{ lookup('env', 'USERNAME') }}" + password: "{{ lookup('env', 'PASSWORD') }}" + validate_certs: false + import_buffer: "{ \"SystemConfiguration\": {\"Components\": [ + { \"FQDD\": \"iDRAC.Embedded.1\",\"Attributes\": [{ \"Name\": \"Time.1#Timezone\", + \"Value\": \"UTC\", + \"Set On Import\": \"True\", + \"Comment\": \"Read and Write\" }]},{ \"FQDD\": + \"RAID.Integrated.1-1\",\"Attributes\": [{ \"Name\": \"RAIDrebuildRate\", + \"Value\": \"31\", + \"Set On Import\": \"True\", + \"Comment\": \"Read and Write\" }]}]}}" diff --git a/roles/idrac_import_server_config_profile/tasks/main.yml b/roles/idrac_import_server_config_profile/tasks/main.yml new file mode 100644 index 000000000..feabbef23 --- /dev/null +++ b/roles/idrac_import_server_config_profile/tasks/main.yml @@ -0,0 +1,31 @@ +--- +# tasks file for idrac_import_server_config_profile + +- name: Importing the SCP components + dellemc.openmanage.idrac_server_config_profile: + idrac_ip: "{{ hostname }}" + idrac_port: "{{ https_port }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + ca_path: "{{ ca_path | default(omit) }}" + validate_certs: "{{ validate_certs }}" + timeout: "{{ https_timeout }}" + share_name: "{{ share_parameters.share_name | default(omit) }}" + scp_file: "{{ share_parameters.scp_file | default(omit) }}" + share_user: "{{ share_parameters.share_user | default(omit) }}" + share_password: "{{ share_parameters.share_password | default(omit) }}" + proxy_support: "{{ share_parameters.proxy_support | default(omit) }}" + proxy_type: "{{ share_parameters.proxy_type | default(omit) }}" + proxy_server: "{{ share_parameters.proxy_server | default(omit) }}" + proxy_port: "{{ share_parameters.proxy_port | default(omit) }}" + proxy_username: "{{ share_parameters.proxy_username | default(omit) }}" + proxy_password: "{{ share_parameters.proxy_password | default(omit) }}" + ignore_certificate_warning: "{{ share_parameters.ignore_certificate_warning | default(omit) }}" + import_buffer: "{{ import_buffer | default(omit) | string }}" + target: "{{ target }}" + shutdown_type: "{{ shutdown_type }}" + end_host_power_state: "{{ end_host_power_state }}" + command: 'import' + job_wait: "{{ job_wait }}" + register: idrac_import_server_config_profile_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_import_server_config_profile/tests/inventory b/roles/idrac_import_server_config_profile/tests/inventory new file mode 100644 index 000000000..878877b07 --- /dev/null +++ b/roles/idrac_import_server_config_profile/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/idrac_import_server_config_profile/tests/test.yml b/roles/idrac_import_server_config_profile/tests/test.yml new file mode 100644 index 000000000..7623255a8 --- /dev/null +++ b/roles/idrac_import_server_config_profile/tests/test.yml @@ -0,0 +1,5 @@ +--- +- name: Importing server config profile for iDRAC + hosts: localhost + roles: + - idrac_import_server_config_profile diff --git a/roles/idrac_import_server_config_profile/vars/main.yml b/roles/idrac_import_server_config_profile/vars/main.yml new file mode 100644 index 000000000..d7a09dd75 --- /dev/null +++ b/roles/idrac_import_server_config_profile/vars/main.yml @@ -0,0 +1,3 @@ +--- +# vars file for idrac_import_server_config_profile +job_wait: true diff --git a/roles/idrac_os_deployment/README.md b/roles/idrac_os_deployment/README.md new file mode 100644 index 000000000..61ea2ca49 --- /dev/null +++ b/roles/idrac_os_deployment/README.md @@ -0,0 +1,297 @@ +# idrac_os_deployment + +Role to deploy specified operating system and version on the servers. +This Role performs the following. +1. Download iso as a local copy +2. Create a kickstart file using jinja template +3. Extract ISO +4. Enable to use kickstart file in the extracted ISO +5. Compile custom ISO +6. Copy ISO to destination share location +7. Mount the ISO as virtual media (virtual CD) in idrac +8. Set boot target to cd and enable a reboot to cd once +9. Track for the OS deployment using the specified time +10. Eject the virtual media + +## Requirements + +### Development +Requirements to develop and contribute to the role. +``` +ansible +docker +molecule +python +``` +### Production +Requirements to use the role. +``` +ansible +python +genisoimage +xorriso +syslinux +isomd5sum +wget +``` + +### Ansible collections +Collections required to use the role +``` +dellemc.openmanage +ansible.posix +``` + +## Role Variables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameRequiredDefault ValueChoicesTypeDescription
hostnametruestriDRAC IP Address
usernametruestriDRAC username
passwordtruestriDRAC user password.
https_portfalse443intiDRAC port.
validate_certsfalsetrueboolIf C(false), the SSL certificates will not be validated.
Configure C(false) only on personally controlled sites where self-signed certificates are used.
ca_pathfalsepathThe Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
https_timeoutfalse30int The HTTPS socket level timeout in seconds.
os_nametruestrThe operating system version to match the jinja template of the kickstart file.
Currently only C(RHEL) supported.
os_versiontruestrThe operating system name to match the jinja template of the kickstart file.
Supported versions for C(RHEL) are 9.x and 8.x
kickstart_filefalsepathLocal path of the kickstart file.
Generation of kickstart file will be ignored if a kickstart file is provided.
source_isotruedictNetwork share or local path of the ISO to download.
     pathtruepathLocal path or network share path of the ISO.
CIFS, NFS, HTTP, HTTPS, and FTP shares are supported.
     usernamefalsestrUsername of the network share.
     passwordfalsestrPassword of the network share.
destination_pathtruedictLocal path or network path to download the ISO.
Share need to have a write permission to copy the generated ISO.
Only CIFS and NFS are supported.
     pathtruepathPath of the network share to copy the customized ISO.
     usernamefalsestrUsername of the network share destination of customized ISO.
     passwordfalsestrPassword of the network share destination of customized ISO.
os_waitfalsetrueboolWait for the OS deployment to finish.
os_wait_timefalse30intTime in minutes to wait for the OS deployment to finish.
eject_isofalsetrueboolEject the virtual media (ISO) after the tracking of OS deployment is finished.
+ +## Fact variables + + + + + + + + + + + + + + + + +
NameSampleDescription
idrac_os_deployment_messageSuccessfully deployed the Operating SystemOutput of the OS deployment role.
+ +## Examples +----- + +``` +- name: Install RHEL OS with kickstart file + ansible.builtin.import_role: + name: idrac_os_deployment + vars: + hostname: 192.168.0.1 + username: root + password: password + ca_path: path/to/ca + os_name: RHEL + os_version: 9.1 + kickstart_file: "/path/to/rhel_ks.cfg" + source_iso: + path: //192.168.0.2/cifs_share/path/to/RHEL_9x.iso + username: administrator + password: password + destination_path: + path: 192.1.2.3:/path/to/nfshare + +- name: Generate Kickstart file and install RHEL OS + ansible.builtin.import_role: + name: idrac_os_deployment + vars: + hostname: 192.168.0.1 + username: root + password: password + ca_path: path/to/ca + os_name: RHEL + os_version: 8.1 + source_iso: + path: https://share_address/to/iso + username: https_user + password: password + destination_path: + path: //192.168.0.2/path/cifsshare + username: cifs_user + password: password +``` + +## Author Information +------------------ + +Dell Technologies
+Jagadeesh N V (Jagadeesh.N.V@Dell.com) 2023 \ No newline at end of file diff --git a/roles/idrac_os_deployment/defaults/main/main.yml b/roles/idrac_os_deployment/defaults/main/main.yml new file mode 100644 index 000000000..e278a1bbe --- /dev/null +++ b/roles/idrac_os_deployment/defaults/main/main.yml @@ -0,0 +1,7 @@ +--- +https_port: 443 +https_timeout: 30 +validate_certs: true +os_wait_time: 30 +eject_iso: true +os_wait: true diff --git a/roles/idrac_os_deployment/defaults/main/rhel.yml b/roles/idrac_os_deployment/defaults/main/rhel.yml new file mode 100644 index 000000000..8fadadde4 --- /dev/null +++ b/roles/idrac_os_deployment/defaults/main/rhel.yml @@ -0,0 +1,16 @@ +rhel_keyboard: us +rhel_lang: en_US +rhel_timezone: ["America/New_York", "--utc"] +rhel_rootpw: "" +rhel_iscrypted: false +rhel_reboot: true +rhel_install_source: cdrom # nfs --server=nfs://10.1.2.3 --dir=/ins/tree +rhel_bootloader: [] # RHEL 8 and 9 have different defaults +rhel_zerombr: true +rhel_clearpart: ["--all", "--initlabel"] +rhel_autopart: [] +rhel_firstboot: ["--disable"] +rhel_firewall: ["--enabled"] +rhel_selinux: ["--enforcing"] +rhel_packages: ["@^minimal-environment"] +rhel_network: false diff --git a/roles/idrac_os_deployment/handlers/main.yml b/roles/idrac_os_deployment/handlers/main.yml new file mode 100644 index 000000000..3f0f3e251 --- /dev/null +++ b/roles/idrac_os_deployment/handlers/main.yml @@ -0,0 +1,21 @@ +--- +# handlers file for idrac_os_deployment +- name: Unmount the share paths + become: true + delegate_to: localhost + ansible.posix.mount: + state: unmounted + path: "{{ item }}" + with_items: + - "{{ idrac_osd_mount_path }}/custom_iso_mount" + - "{{ idrac_osd_mount_path }}/source_iso_mount" + failed_when: false + +- name: Clean up the working directory + become: true + delegate_to: localhost + ansible.builtin.file: + path: "{{ working_dir.path }}" + state: absent + failed_when: false + when: working_dir is defined diff --git a/roles/idrac_os_deployment/meta/argument_specs.yml b/roles/idrac_os_deployment/meta/argument_specs.yml new file mode 100644 index 000000000..605e49081 --- /dev/null +++ b/roles/idrac_os_deployment/meta/argument_specs.yml @@ -0,0 +1,103 @@ +--- +argument_specs: + main: + version_added: "7.4.0" + short_description: Role to deploy specified operating system and version on the servers. + description: Role to deploy specified operating system and version on the servers. + options: + hostname: + required: true + type: str + description: iDRAC IP Address. + username: + required: true + type: str + description: iDRAC username. + password: + required: true + 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. + 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 + https_timeout: + description: The socket level timeout in seconds. + type: int + default: 30 + os_name: + type: str + description: + - The operating system name to match the jinja template of the kickstart file. + - Currently only C(RHEL) supported. + required: true + os_version: + type: str + description: + - The operating system version to match the jinja template of the kickstart file. + - Supported versions for C(RHEL) are 9.x and 8.x + required: true + source_iso: + type: dict + description: Network share or local path of the ISO. + required: true + options: + path: + type: path + description: + - Local path or network share path of the ISO. + - CIFS, NFS, HTTP, HTTPS, and FTP shares are supported. + required: true + username: + type: str + description: Username of the network share. + password: + type: str + description: Password of the network share. + destination_path: + type: dict + description: + - Share path to mount the ISO to iDRAC. + - Share needs to have a write permission to copy the generated ISO. + - Only CIFS and NFS are supported. + required: true + options: + path: + type: path + description: Path of the network share to copy the customized ISO. + required: true + username: + type: str + description: Username of the network share destination of customized ISO. + password: + type: str + description: Password of the network share destination of customized ISO. + kickstart_file: + type: path + description: + - Local path of the kickstart file. + - Generation of kickstart file will be ignored if a kickstart file is provided. + os_wait: + default: true + type: bool + description: + - Wait for the OS deployment to finish. + os_wait_time: + description: + - Time in minutes to wait for the OS deployment to finish. + default: 30 + type: int + eject_iso: + description: + - Eject the virtual media (ISO) after the tracking of OS deployment is finished. + default: true + type: bool diff --git a/roles/idrac_os_deployment/meta/main.yml b/roles/idrac_os_deployment/meta/main.yml new file mode 100644 index 000000000..5e5def8b4 --- /dev/null +++ b/roles/idrac_os_deployment/meta/main.yml @@ -0,0 +1,17 @@ +galaxy_info: + role_name: idrac_os_deployment + author: "Jagadeesh N V" + description: The role helps to deploy the operating system on server. + company: Dell Technologies + license: GPL-3.0-only + min_ansible_version: "2.13" + galaxy_tags: [] + platforms: + - name: EL + versions: + - "9" + - "8" + - name: Ubuntu + versions: + - jammy +dependencies: [] diff --git a/roles/idrac_os_deployment/tasks/clean_up.yml b/roles/idrac_os_deployment/tasks/clean_up.yml new file mode 100644 index 000000000..fe9b95804 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/clean_up.yml @@ -0,0 +1,24 @@ +--- +# Clean up tmp dir and mounted paths +- name: Rescue-Unmount the share paths + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + state: unmounted + path: "{{ item }}" + with_items: + - "{{ idrac_osd_mount_path }}/custom_iso_mount" + - "{{ idrac_osd_mount_path }}/source_iso_mount" + failed_when: false + when: working_dir is defined + no_log: true + +- name: Rescue-Clean up the working directory + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ working_dir.path }}" + state: absent + failed_when: false + when: working_dir is defined + no_log: true diff --git a/roles/idrac_os_deployment/tasks/copy_dest_iso.yml b/roles/idrac_os_deployment/tasks/copy_dest_iso.yml new file mode 100644 index 000000000..32d69ab1e --- /dev/null +++ b/roles/idrac_os_deployment/tasks/copy_dest_iso.yml @@ -0,0 +1,32 @@ +- name: Custom iso file permission + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ custom_iso }}" + mode: '0755' + +- name: Copy custom iso to mounted path + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.copy: + src: "{{ custom_iso }}" + remote_src: true + dest: "{{ idrac_osd_mount_path }}/custom_iso_mount" + mode: '0755' + +- name: Remove custom iso from tmp + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ custom_iso }}" + state: absent + failed_when: false + +- name: Remove the extracted directory + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ iso_extract_dir.path }}" + state: absent + failed_when: false + no_log: "{{ idrac_osd_std_log }}" diff --git a/roles/idrac_os_deployment/tasks/get_iso.yml b/roles/idrac_os_deployment/tasks/get_iso.yml new file mode 100644 index 000000000..07b4bb333 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/get_iso.yml @@ -0,0 +1,130 @@ +- name: Check if kickstart readable + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.stat: + path: "{{ kickstart_file }}" + register: ks_read + +- name: Kickstart read error + ansible.builtin.fail: + msg: "Kickstart file does not exist or is not readable {{ kickstart_file }}" + when: not ks_read.stat.exists + +- name: Set download command + ansible.builtin.set_fact: + idrac_osd_wget_cmd: "wget {{ source_iso.path }} --directory-prefix={{ working_dir.path }} + --no-check-certificate{% if source_iso.username is defined and source_iso.username %} + --user={{ source_iso.username }} --password={{ source_iso.password }}{%endif %}" + when: iso_share_type in ['HTTP', 'HTTPS', 'FTP'] + no_log: true + +- name: Download iso from http, https or ftp + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.command: "{{ idrac_osd_wget_cmd }}" + register: wget_iso_cmd + when: iso_share_type in ['HTTP', 'HTTPS', 'FTP'] + changed_when: wget_iso_cmd.rc == 0 + failed_when: false + no_log: true + +- name: Dowload iso failed + ansible.builtin.fail: + msg: "Download of ISO from {{ source_iso.path }} failed. Please check the source URI or credentials." + when: + - iso_share_type in ['HTTP', 'HTTPS', 'FTP'] + - wget_iso_cmd.failed or wget_iso_cmd.rc != 0 + +- name: Set local path of source iso + ansible.builtin.set_fact: + src_iso: "{{ working_dir.path }}/{{ source_iso.path | basename }}" + downloaded_iso: true + when: iso_share_type in ['HTTP', 'HTTPS', 'FTP'] + +- name: Mounting NFS volume to localhost + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + src: "{{ source_iso.path | dirname }}" + path: "{{ idrac_osd_mount_path }}/source_iso_mount" + state: mounted + fstype: nfs + register: nfs_mount_path + when: iso_share_type == 'NFS' + ignore_errors: true + +- name: NFS path mounting failed + ansible.builtin.fail: + msg: "Mounting source NFS share failed." + when: iso_share_type == 'NFS' and nfs_mount_path.failed + +- name: Mounting CIFS volume to localhost + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + src: "{{ source_iso.path | dirname }}" + path: "{{ idrac_osd_mount_path }}/source_iso_mount" + state: mounted + opts: "rw,username={{ source_iso.username | split('@') | first }},password={{ source_iso.password }}" + fstype: cifs + register: cifs_mount_path + when: iso_share_type == 'CIFS' + no_log: true + ignore_errors: true + +- name: CIFS path mounting failed + ansible.builtin.fail: + msg: "Mounting source CIFS share failed. Please check the path or credentials" + when: iso_share_type == 'CIFS' and cifs_mount_path.failed + +- name: Set local path of source iso NFS + ansible.builtin.set_fact: + src_iso: "{{ nfs_mount_path.name }}/{{ source_iso.path | basename }}" + when: iso_share_type == 'NFS' + +- name: Set local path of source iso CIFS + ansible.builtin.set_fact: + src_iso: "{{ cifs_mount_path.name }}/{{ source_iso.path | basename }}" + when: iso_share_type == 'CIFS' + +- name: Get temp dir + ansible.builtin.set_fact: + work_path: "{{ working_dir.path }}" + +- name: Set local path of source iso + ansible.builtin.set_fact: + src_iso: "{{ source_iso.path }}" + when: iso_share_type == 'Local' + +- name: Get iso name + ansible.builtin.set_fact: + iso_basename: "{{ src_iso | splitext | list | first | basename }}" + +- name: Check if iso readable + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.stat: + path: "{{ src_iso }}" + register: source_iso_mount + +- name: Source iso read error + ansible.builtin.fail: + msg: "Source iso does not exist or is not mounted properly at path {{ src_iso }}" + when: not source_iso_mount.stat.exists + +- name: Create a directory if it does not exist + ansible.builtin.file: + path: "{{ working_dir.path }}/{{ iso_basename }}" + state: directory + mode: '0755' + register: iso_extract_dir + +- name: Extract iso + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.command: "xorriso -osirrox on -indev {{ src_iso }} -extract / {{ iso_extract_dir.path }}" + register: extract_cmd_out + when: source_iso_mount.stat.exists + changed_when: extract_cmd_out.rc == 0 + failed_when: extract_cmd_out.rc != 0 + +- name: Set extracted dir + ansible.builtin.set_fact: + iso_dir: "{{ iso_extract_dir.path }}" diff --git a/roles/idrac_os_deployment/tasks/install_packages.yml b/roles/idrac_os_deployment/tasks/install_packages.yml new file mode 100644 index 000000000..3dd173e93 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/install_packages.yml @@ -0,0 +1,61 @@ +- name: Install iso utils to RedHat Ansible Controller + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.yum: + name: + - genisoimage + - xorriso + - syslinux + - isomd5sum + state: present + when: ansible_facts['os_family']|lower == 'redhat' + +- name: Install iso utils to Ubuntu Ansible Controller + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.apt: + name: + - genisoimage + - xorriso + - syslinux-utils + - isomd5sum + state: present + when: ansible_facts['os_family']|lower == 'debian' + +- name: Initializing iso path type + ansible.builtin.set_fact: + iso_share_type: null + downloaded_iso: false + +- name: Checking network share type is CIFS, HTTPS, HTTP, FTP + ansible.builtin.set_fact: + iso_share_type: "{{ item.value if source_iso.path.startswith(item.key) }}" + with_dict: {'https://': 'HTTPS', 'http://': 'HTTP', 'ftp://': 'FTP', '//': 'CIFS', '\\': 'CIFS'} + when: not iso_share_type + +- name: Checking network share type is NFS, Local + ansible.builtin.set_fact: + iso_share_type: "{{ 'Local' if ':' not in source_iso.path else 'NFS' }}" + when: not iso_share_type + +- name: Install wget for http,https,ftp + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.yum: + name: + - wget + state: present + when: + - ansible_facts['os_family']|lower == 'redhat' + - iso_share_type in ['HTTP', 'HTTPS', 'FTP'] + +- name: Install wget for Ubuntu Ansible Controller + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.apt: + name: + - wget + state: present + when: + - ansible_facts['os_family']|lower == 'debian' + - iso_share_type in ['HTTP', 'HTTPS', 'FTP'] diff --git a/roles/idrac_os_deployment/tasks/kickstart_generator.yml b/roles/idrac_os_deployment/tasks/kickstart_generator.yml new file mode 100644 index 000000000..0fa71d054 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/kickstart_generator.yml @@ -0,0 +1,22 @@ +- name: Check if rootpw exists + ansible.builtin.fail: + msg: "Please provide the root password." + when: rhel_rootpw | length == 0 + +- name: Generate kickstart file + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.template: + src: "{{ os_name }}_{{ os_version | string | split('.') | first }}.j2" + dest: "{{ working_dir.path }}/{{ os_name }}_KS_{{ hostname }}.cfg" + mode: "0755" + register: ks_generate + ignore_errors: true + +- name: Kickstart generation failed + ansible.builtin.fail: + msg: "Kickstart generation failed. Please provide the supported OS name and version" + when: ks_generate.failed + +- name: Set ks file for specific idrac + ansible.builtin.set_fact: + kickstart_file: "{{ ks_generate.dest }}" diff --git a/roles/idrac_os_deployment/tasks/main.yml b/roles/idrac_os_deployment/tasks/main.yml new file mode 100644 index 000000000..34ba0e076 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/main.yml @@ -0,0 +1,66 @@ +# tasks file for idrac_os_deployment + +- name: Role to deploy OS + block: + - name: Set OS variables + ansible.builtin.set_fact: + idrac_osd_host: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" + os_key: "{{ os_name | lower }}" + + - name: Check supported OS. + ansible.builtin.fail: + msg: "OS {{ os_name }} or version {{ os_version }} is not supported." + when: + - (os_name not in supported_os) or (os_version | string | split('.') | first) not in supported_os_version[os_name] + + - name: Initial probe destination + ansible.builtin.include_tasks: probe_dest.yml + + - name: Install packages on controller + ansible.builtin.include_tasks: install_packages.yml + when: not dest_iso_exists + + - name: Generate kickstart file + ansible.builtin.include_tasks: kickstart_generator.yml + when: + - kickstart_file is not defined + - not dest_iso_exists + + - name: Get the iso + ansible.builtin.include_tasks: get_iso.yml + when: not dest_iso_exists + + - name: Edit rhel iso script + ansible.builtin.include_tasks: "{{ os_key }}_iso_edit.yml" + when: not dest_iso_exists + + - name: Copy iso to destination share + ansible.builtin.include_tasks: copy_dest_iso.yml + when: not dest_iso_exists + + - name: Start virtual media + ansible.builtin.include_tasks: virtual_media_wait.yml + + - name: Unmount and clean up + ansible.builtin.include_tasks: unmount_cleanup.yml + + rescue: + - name: Clean up + ansible.builtin.include_tasks: clean_up.yml + + - name: Compile the failure message + ansible.builtin.set_fact: + idrac_os_deployment_failure: "{{ ansible_failed_result | combine({'failed_task_name': ansible_failed_task.name}) }}" + no_log: true + when: ansible_failed_task.name not in idrac_osd_no_loggers + + - name: Compile the failure message for no logs + ansible.builtin.set_fact: + idrac_os_deployment_failure: "{{ {'msg': ansible_failed_result.msg} | combine({'failed_task_name': ansible_failed_task.name}) }}" + no_log: true + when: ansible_failed_task.name in idrac_osd_no_loggers + + - name: On failure + ansible.builtin.debug: + var: idrac_os_deployment_failure + failed_when: true diff --git a/roles/idrac_os_deployment/tasks/probe_dest.yml b/roles/idrac_os_deployment/tasks/probe_dest.yml new file mode 100644 index 000000000..8211a235d --- /dev/null +++ b/roles/idrac_os_deployment/tasks/probe_dest.yml @@ -0,0 +1,86 @@ +- name: Clean slate - Init unmount + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + state: unmounted + path: "{{ item }}" + with_items: + - "{{ idrac_osd_mount_path }}/custom_iso_mount" + - "{{ idrac_osd_mount_path }}/source_iso_mount" + failed_when: false + +- name: Create working directory + ansible.builtin.tempfile: + state: directory + prefix: omam_osd + register: working_dir + +- name: Initializing destination iso path type + ansible.builtin.set_fact: + idrac_osd_no_loggers: + - Set download command + - Mounting dest CIFS volume + - Mounting CIFS volume to localhost + - Download iso from http, https or ftp + - Initializing iso path type and aliasing idrac opts + dest_iso_share_type: null + dest_iso_exists: false + custom_iso: "{{ working_dir.path }}/{{ os_key }}_{{ os_version }}_{{ hostname }}.iso" + +- name: Checking network share type is CIFS + ansible.builtin.set_fact: + dest_iso_share_type: "{{ item.value if destination_path.path.startswith(item.key) }}" + with_dict: {'//': 'CIFS', '\\': 'CIFS'} + when: not dest_iso_share_type + +- name: Default is NFS + ansible.builtin.set_fact: + dest_iso_share_type: NFS + when: not dest_iso_share_type + +- name: Mounting NFS volume to localhost + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + src: "{{ destination_path.path }}" + path: "{{ idrac_osd_mount_path }}/custom_iso_mount" + state: mounted + fstype: nfs + opts: rw,sync,hard + register: dest_mount_path + when: dest_iso_share_type == 'NFS' + +- name: NFS path mounting failed + ansible.builtin.fail: + msg: "Mounting destiantion NFS share failed." + when: dest_iso_share_type == 'NFS' and dest_mount_path.failed + +- name: Mounting dest CIFS volume + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + src: "{{ destination_path.path }}" + path: "{{ idrac_osd_mount_path }}/custom_iso_mount" + state: mounted + opts: "rw,username={{ destination_path.username | split('@') | first }},password={{ destination_path.password }}" + fstype: cifs + register: dest_mount_path + when: dest_iso_share_type == 'CIFS' + no_log: true + +- name: CIFS path mounting failed + ansible.builtin.fail: + msg: "Mounting destination CIFS share failed. Please check the path or credentials." + when: dest_iso_share_type == 'CIFS' and dest_mount_path.failed + +- name: Check if dest exists + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.stat: + path: "{{ idrac_osd_mount_path }}/custom_iso_mount/{{ custom_iso | basename }}" + register: dest_iso_mount + +- name: Set dest iso exists true + ansible.builtin.set_fact: + dest_iso_exists: true + when: dest_iso_mount.stat.exists diff --git a/roles/idrac_os_deployment/tasks/rhel_iso_edit.yml b/roles/idrac_os_deployment/tasks/rhel_iso_edit.yml new file mode 100644 index 000000000..5070982a4 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/rhel_iso_edit.yml @@ -0,0 +1,96 @@ +- name: Copy KS to extracted + become: true + ansible.builtin.copy: + src: "{{ kickstart_file }}" + dest: "{{ iso_dir }}/{{ rhel_ks_filename }}" + mode: '0755' + +- name: Set KickStart location + ansible.builtin.set_fact: + ks_location: "{{ rhel_ks_dest_prefix }}{{ rhel_ks_filename }}" + +- name: Append ks path to the linux boot menu + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.lineinfile: + path: "{{ item }}" + regexp: "^(.*inst.stage2=hd:LABEL.*?)( inst.ks={{ ks_location }})?$" + backrefs: true + firstmatch: true + line: '\1 inst.ks={{ ks_location }}' + with_items: + - "{{ iso_dir }}/isolinux/isolinux.cfg" + - "{{ iso_dir }}/EFI/BOOT/grub.cfg" + +- name: Menu default remove all occurrences + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.lineinfile: + path: "{{ iso_dir }}/isolinux/isolinux.cfg" + search_string: "menu default" + state: absent + +- name: Menu default insert before kernel vmlinuz isolinux + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.lineinfile: + path: "{{ iso_dir }}/isolinux/isolinux.cfg" + line: ' menu default' + firstmatch: true + insertbefore: '.*kernel vmlinuz.*' + +- name: Grub menu default 0 + delegate_to: "{{ idrac_osd_host }}" + become: true + ansible.builtin.lineinfile: + path: "{{ iso_dir }}/EFI/BOOT/grub.cfg" + line: 'set default="0"' + firstmatch: true + regexp: '^set default=' + +- name: Get iso LABEL + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.command: "blkid -s LABEL -o value {{ src_iso }}" + register: blkid_output + changed_when: blkid_output.rc != 0 + +- name: Set iso LABEL + ansible.builtin.set_fact: + iso_label: "{{ blkid_output.stdout | trim }}" + +- name: Remove source iso if downloaded + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ src_iso }}" + state: absent + when: downloaded_iso + failed_when: false + +- name: Compile custom ISO + become: true + ansible.builtin.command: + chdir: "{{ iso_extract_dir.path }}" + cmd: "mkisofs -o {{ custom_iso }} -b isolinux/isolinux.bin -J -R -l -c isolinux/boot.cat + -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img + -no-emul-boot -graft-points -joliet-long -V {{ iso_label }} ." + register: mkisofs_output + changed_when: mkisofs_output.rc == 0 + failed_when: mkisofs_output.rc != 0 + no_log: "{{ idrac_osd_std_log }}" + +- name: Post-process ISO image with isohybrid + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.command: isohybrid --uefi {{ custom_iso }} + register: isohybrid_output + changed_when: isohybrid_output.rc == 0 + ignore_errors: true + +- name: Add correct checksum to iso + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.command: implantisomd5 {{ custom_iso }} + register: checksum_output + changed_when: checksum_output.rc == 0 + ignore_errors: true diff --git a/roles/idrac_os_deployment/tasks/unmount_cleanup.yml b/roles/idrac_os_deployment/tasks/unmount_cleanup.yml new file mode 100644 index 000000000..6efe49fb1 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/unmount_cleanup.yml @@ -0,0 +1,33 @@ +- name: Remove custom iso + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ idrac_osd_mount_path }}/custom_iso_mount/{{ custom_iso | basename }}" + state: absent + failed_when: false + when: idrac_osd_cleanup_custom_iso and os_wait + +- name: Unmount the share paths + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.posix.mount: + state: unmounted + path: "{{ item }}" + with_items: + - "{{ idrac_osd_mount_path }}/custom_iso_mount" + - "{{ idrac_osd_mount_path }}/source_iso_mount" + failed_when: false + +- name: Clean up the working directory + become: true + delegate_to: "{{ idrac_osd_host }}" + ansible.builtin.file: + path: "{{ working_dir.path }}" + state: absent + failed_when: false + +- name: OS install complete message + ansible.builtin.set_fact: + idrac_os_deployment_message: "Successfully deployed the Operating System." + when: os_wait + changed_when: true diff --git a/roles/idrac_os_deployment/tasks/virtual_media_wait.yml b/roles/idrac_os_deployment/tasks/virtual_media_wait.yml new file mode 100644 index 000000000..9950833c9 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/virtual_media_wait.yml @@ -0,0 +1,67 @@ +- name: Initializing iso path type and aliasing idrac opts + ansible.builtin.set_fact: + idrac_opts: &idrac_opts + idrac_ip: "{{ hostname }}" + idrac_user: "{{ username }}" + idrac_password: "{{ password }}" + idrac_port: "{{ https_port }}" + validate_certs: "{{ validate_certs }}" + ca_path: "{{ ca_path | default(omit) }}" + no_log: true + +- name: Clear the Virtual Media + dellemc.openmanage.idrac_virtual_media: + <<: *idrac_opts + force: true + virtual_media: + - insert: false + failed_when: false + +- name: Load the custom iso to Virtual Media slot 1 + dellemc.openmanage.idrac_virtual_media: + <<: *idrac_opts + force: true + virtual_media: + - insert: true + image: "{{ destination_path.path }}/{{ custom_iso | basename }}" + username: "{{ destination_path.username | default(omit) }}" + password: "{{ destination_path.password | default(omit) }}" + register: idrac_vm_insert + +- name: Virtual Media mount failed + ansible.builtin.fail: + msg: "Mounting as iDRAC virtual CD failed." + when: idrac_vm_insert.failed + +- name: Configure the boot source override mode. + dellemc.openmanage.idrac_boot: + <<: *idrac_opts + boot_source_override_mode: uefi + boot_source_override_target: cd + boot_source_override_enabled: once + reset_type: force_restart + register: idrac_boot_once + failed_when: false + +- name: Boot once iDRAC error + ansible.builtin.fail: + msg: "Setting boot from virtual ISO task has failed. Check the server manually for OS installation status and proceed accordingly." + when: idrac_boot_once.failed + +- name: OS install message + ansible.builtin.set_fact: + idrac_os_deployment_message: "Successfully loaded the ISO and started OS installation." + changed_when: true + +- name: Wait for OS install wait time + ansible.builtin.wait_for: + timeout: "{{ (os_wait_time * 60) }}" + when: os_wait + +- name: Eject the custom iso + dellemc.openmanage.idrac_virtual_media: + <<: *idrac_opts + force: true + virtual_media: + - insert: false + when: os_wait and eject_iso diff --git a/roles/idrac_os_deployment/templates/RHEL_8.j2 b/roles/idrac_os_deployment/templates/RHEL_8.j2 new file mode 100644 index 000000000..de4903a08 --- /dev/null +++ b/roles/idrac_os_deployment/templates/RHEL_8.j2 @@ -0,0 +1,31 @@ +eula --agreed +lang {{ rhel_lang }} +keyboard {{ rhel_keyboard }} +timezone {{ rhel_timezone|join(' ') }} +{% if rhel_iscrypted is defined and rhel_iscrypted == true %} +rootpw {{ rhel_rootpw }} --iscrypted +{% else %} +rootpw {{ rhel_rootpw }} --plaintext +{% endif %} +{{ rhel_install_source }} +bootloader --append="rhgb quiet crashkernel=auto" {{ rhel_bootloader|join(' ') }} +{% if rhel_zerombr is defined and rhel_zerombr == true %} +zerombr +{% endif %} +{% set my_dict = {'clearpart': rhel_clearpart, 'autopart': rhel_autopart, 'firstboot': rhel_firstboot, +'network': rhel_network, 'firewall': rhel_firewall, 'selinux': rhel_selinux} %} +{% for key,value in my_dict.items() %} +{% if value is defined and value != false %} +{{ ([key] + value)|join(' ') }} +{% endif %} +{% endfor %} +{% if rhel_reboot is defined and rhel_reboot == true %} +reboot +{% endif %} +{% if rhel_packages is defined and rhel_packages != false and rhel_packages != [] %} +%packages +{% for pkg in rhel_packages %} +{{ pkg }} +{% endfor %} +%end +{% endif %} diff --git a/roles/idrac_os_deployment/templates/RHEL_9.j2 b/roles/idrac_os_deployment/templates/RHEL_9.j2 new file mode 100644 index 000000000..0721986e0 --- /dev/null +++ b/roles/idrac_os_deployment/templates/RHEL_9.j2 @@ -0,0 +1,31 @@ +eula --agreed +lang {{ rhel_lang }} +keyboard {{ rhel_keyboard }} +timezone {{ rhel_timezone|join(' ') }} +{% if rhel_iscrypted is defined and rhel_iscrypted == true %} +rootpw {{ rhel_rootpw }} --iscrypted +{% else %} +rootpw {{ rhel_rootpw }} --plaintext +{% endif %} +{{ rhel_install_source }} +bootloader --append="rhgb quiet crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M" {{ rhel_bootloader|join(' ') }} +{% if rhel_zerombr is defined and rhel_zerombr == true %} +zerombr +{% endif %} +{% set my_dict = {'clearpart': rhel_clearpart, 'autopart': rhel_autopart, 'firstboot': rhel_firstboot, +'network': rhel_network, 'firewall': rhel_firewall, 'selinux': rhel_selinux} %} +{% for key,value in my_dict.items() %} +{% if value is defined and value != false %} +{{ ([key] + value)|join(' ') }} +{% endif %} +{% endfor %} +{% if rhel_reboot is defined and rhel_reboot == true %} +reboot +{% endif %} +{% if rhel_packages is defined and rhel_packages != false and rhel_packages != [] %} +%packages +{% for pkg in rhel_packages %} +{{ pkg }} +{% endfor %} +%end +{% endif %} diff --git a/roles/idrac_os_deployment/tests/inventory b/roles/idrac_os_deployment/tests/inventory new file mode 100644 index 000000000..5df533bdf --- /dev/null +++ b/roles/idrac_os_deployment/tests/inventory @@ -0,0 +1,14 @@ +hostname: idrac_host +username: idrac_user +password: idrac_password +os_name: RHEL +os_version: 9.1 +# kickstart_file: "/home/jag/os_deploy/rhel_9.txt" +rhel_rootpw: "plaintext_password" +rhel_iscrypted: false +rhel_timezone: ["Asia/Kolkata"] +rhel_lang: en_IN +rhel_network: + - --device=em1 + - --bootproto=dhcp + - --hostname=redhatbox diff --git a/roles/idrac_os_deployment/tests/test.yml b/roles/idrac_os_deployment/tests/test.yml new file mode 100644 index 000000000..156ec2824 --- /dev/null +++ b/roles/idrac_os_deployment/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: Deploy specified operating system on the servers + hosts: localhost + remote_user: root + roles: + - idrac_os_deployment diff --git a/roles/idrac_os_deployment/vars/main.yml b/roles/idrac_os_deployment/vars/main.yml new file mode 100644 index 000000000..dc702d6dc --- /dev/null +++ b/roles/idrac_os_deployment/vars/main.yml @@ -0,0 +1,12 @@ +--- +# vars file for idrac_os_deployment +idrac_os_deployment_ignore_errors: true +rhel_ks_filename: "ks.cfg" +rhel_ks_dest_prefix: "cdrom:/" +idrac_osd_cleanup_custom_iso: true +idrac_osd_mount_path: "/mnt" +idrac_osd_std_log: true +supported_os: + - RHEL +supported_os_version: + RHEL: ["8", "9"] diff --git a/roles/idrac_server_powerstate/.yamllint b/roles/idrac_server_powerstate/.yamllint new file mode 100644 index 000000000..882767605 --- /dev/null +++ b/roles/idrac_server_powerstate/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/idrac_server_powerstate/README.md b/roles/idrac_server_powerstate/README.md new file mode 100644 index 000000000..0b7fc82f7 --- /dev/null +++ b/roles/idrac_server_powerstate/README.md @@ -0,0 +1,217 @@ +# idrac_server_powerstate + +Role to to manage the different power states of the specified device using iDRACs (iDRAC7/8 and iDRAC9 only) for Dell PowerEdge servers. + +## 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameRequiredDefault ValueChoicesTypeDescription
hostnametruestr- iDRAC IP Address
usernametruestr- iDRAC username
passwordtruestr- iDRAC user password.
https_portfalse443int- iDRAC port.
validate_certsfalsetruebool- If C(false), the SSL certificates will not be validated.
- Configure C(false) only on personally controlled sites where self-signed certificates are used.
ca_pathfalsepath- The Privacy Enhanced Mail (PEM) file that contains a CA certificate to be used for the validation.
https_timeoutfalse30int- The HTTPS socket level timeout in seconds.
resource_idfalsestr- The unique identifier of the device being managed.For example- U(https:///redfish/v1/Systems/).
- This option is mandatory for I(base_uri) with multiple devices.
- To get the device details, use the API U(https:///redfish/v1/Systems).
reset_typefalse'On'["ForceOff", "ForceOn", "ForceRestart", "GracefulRestart", "GracefulShutdown", "Nmi", "On", "PowerCycle", "PushPowerButton"]str- This option resets the device.
- If C(ForceOff), Turns off the device immediately.
- If C(ForceOn), Turns on the device immediately.
- If C(ForceRestart), Turns off the device immediately, and then restarts the device.
- If C(GracefulRestart), Performs graceful shutdown of the device, and then restarts the device.
- If C(GracefulShutdown), Performs a graceful shutdown of the device, and the turns off the device.
- If C(Nmi), Sends a diagnostic interrupt to the device. This is usually a non-maskable interrupt (NMI) on x86 device.
- If C(On), Turns on the device.
- If C(PowerCycle), Performs power cycle on the device.
- If C(PushPowerButton), Simulates the pressing of a physical power button on the device.
- When a power control operation is performed, which is not supported on the device, an error message is displayed with the list of operations that can be performed.
+ +## Fact variables + + + + + + + + + + + + + + + +
NameSampleDescription
idrac_server_powerstate_out{"changed": true, + "failed": false, + "msg": "Successfully performed the reset type operation 'GracefulRestart'." +}Module output of the powercycle contol
+ +## Examples +----- + +``` +- name: "Performing force off operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "ForceOff" + +- name: "Performing power on operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "On" + +- name: "Performing graceful restart operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "GracefulRestart" + +- name: "Performing graceful shutdown operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "GracefulShutdown" + +- name: "Performing powercycle operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "PowerCycle" + +- name: "Performing push power button operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "PushPowerButton" + +- name: "Performing force restart operation" + ansible.builtin.include_role: + name: idrac_server_powerstate + vars: + hostname: "192.1.2.1" + username: "username" + password: "password" + ca_path: "/path/to/ca_cert.pem" + reset_type: "ForceRestart" +``` + +## Author Information +------------------ + +Dell Technologies
+Kritika Bhateja (Kritika.Bhateja@Dell.com) 2023 \ No newline at end of file diff --git a/roles/idrac_server_powerstate/defaults/main.yml b/roles/idrac_server_powerstate/defaults/main.yml new file mode 100644 index 000000000..9538ec0a9 --- /dev/null +++ b/roles/idrac_server_powerstate/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# defaults file for idrac_server_powerstate +validate_certs: true +https_timeout: 30 +reset_type: "On" +https_port: 443 diff --git a/roles/idrac_server_powerstate/handlers/main.yml b/roles/idrac_server_powerstate/handlers/main.yml new file mode 100644 index 000000000..032a5a52e --- /dev/null +++ b/roles/idrac_server_powerstate/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for idrac_server_powerstate diff --git a/roles/idrac_server_powerstate/meta/argument_specs.yml b/roles/idrac_server_powerstate/meta/argument_specs.yml new file mode 100644 index 000000000..dc5631c61 --- /dev/null +++ b/roles/idrac_server_powerstate/meta/argument_specs.yml @@ -0,0 +1,70 @@ +--- +argument_specs: + main: + version_added: "7.4.0" + short_description: Role to manage the different power states of the specified device. + description: Role to manage the different power states of the specified device using iDRACs (iDRAC7/8 and iDRAC9 only) for Dell PowerEdge servers. + options: + hostname: + required: true + type: str + description: iDRAC IP Address. + username: + required: true + type: str + description: iDRAC username. + password: + required: true + 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. + 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 + https_timeout: + description: The HTTPS socket level timeout in seconds. + type: int + default: 30 + resource_id: + description: + - The unique identifier of the device being managed. + - This option is mandatory for I(hostname) with multiple devices. + type: str + reset_type: + description: + - This option resets the device. + - If C(ForceOff), Turns off the device immediately. + - If C(ForceOn), Turns on the device immediately. + - If C(ForceRestart), Turns off the device immediately, and then restarts the device. + - If C(GracefulRestart), Performs graceful shutdown of the device, and then restarts the device. + - If C(GracefulShutdown), Performs a graceful shutdown of the device, and the turns off the device. + - If C(Nmi), Sends a diagnostic interrupt to the device. This is usually a non-maskable interrupt (NMI) on x86 device. + - If C(On), Turns on the device. + - If C(PowerCycle), Performs power cycle on the device. + - If C(PushPowerButton), Simulates the pressing of a physical power button on the device. + - When a power control operation is performed, which is not supported on the device, + an error message is displayed with the list of operations that can be performed. + type: str + default: "On" + choices: + [ + "ForceOff", + "ForceOn", + "ForceRestart", + "GracefulRestart", + "GracefulShutdown", + "Nmi", + "On", + "PowerCycle", + "PushPowerButton" + ] diff --git a/roles/idrac_server_powerstate/meta/main.yml b/roles/idrac_server_powerstate/meta/main.yml new file mode 100644 index 000000000..e206309b7 --- /dev/null +++ b/roles/idrac_server_powerstate/meta/main.yml @@ -0,0 +1,54 @@ +galaxy_info: + author: Kritika-Bhateja + description: The role helps to manage the different power states of the specified device. + 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: EL + versions: + - "9" + - "8" + - name: Ubuntu + versions: + - jammy + - name: SLES + versions: + - "15SP3" + - "15SP4" + + 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/roles/idrac_server_powerstate/molecule/default/converge.yml b/roles/idrac_server_powerstate/molecule/default/converge.yml new file mode 100644 index 000000000..8a55588f7 --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/default/converge.yml @@ -0,0 +1,193 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Performing operation on the iDRAC device using default reset_type + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + resource_id: "System.Embedded.1" + + - name: Asserting after performing opeartion using default reset_type + ansible.builtin.assert: + that: |- + ( idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'On'." ) + or + ( idrac_server_powerstate_out.msg == "The device is already powered on." ) + + - name: Performing operation On the iDRAC with invalid resource_id + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + resource_id: "System.Embedded.0" + ignore_errors: true + register: error_msg + + - name: Asserting after performing opeartion with invalid resource_id + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Invalid device Id 'System.Embedded.0' is provided" + - not idrac_server_powerstate_out.changed + + - name: Performing operation 'On' with invalid hostname + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "randomHostname" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + resource_id: "System.Embedded.1" + ignore_errors: true + ignore_unreachable: true + register: error_msg + + - name: Asserting after performing opeartion with invalid hostname + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "" + + - name: Performing operation 'On' with invalid username + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "WrongUsername123" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + resource_id: "System.Embedded.1" + ignore_errors: true + ignore_unreachable: true + register: error_msg + + - name: Asserting after performing opeartion with invalid username + ansible.builtin.assert: + that: + - '"HTTP Error 401" in idrac_server_powerstate_out.msg' + + - name: Performing operation 'On' with invalid password + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "WrongPassword@123" + validate_certs: false + resource_id: "System.Embedded.1" + ignore_errors: true + ignore_unreachable: true + register: error_msg + + - name: Asserting after performing opeartion with invalid password + ansible.builtin.assert: + that: |- + ('"HTTP Error 401" in idrac_server_powerstate_out.msg') + or + ('"urlopen error timed out" in idrac_server_powerstate_out.msg') + + - name: Performing operation 'On' with invalid validate_certs + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: 'someStringValue' + resource_id: "System.Embedded.1" + ignore_errors: true + ignore_unreachable: true + register: error_msg + + - name: Asserting after performing opeartion with invalid validate_certs + ansible.builtin.assert: + that: + - '"Valid booleans include" in idrac_server_powerstate_out.msg' + + - name: Performing operation 'ForceOn' on iDRAC server + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: 'false' + reset_type: 'ForceOn' + resource_id: "System.Embedded.1" + ignore_errors: true + register: error_msg + + - name: Asserting after performing opeartion "ForceOn" + ansible.builtin.assert: + that: + - '"The target device does not support a force on operation." in idrac_server_powerstate_out.msg' + + - name: Fetching all the resource_id using URI + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: uri_out + no_log: true + + - name: Processing resource_id + ansible.builtin.set_fact: + resource_id_list: "{{ uri_out.json | json_query(query) }}" + vars: + query: Members[*]."@odata.id" + + - name: Splitting the resource_id and picking last + ansible.builtin.set_fact: + resource_id_list_split: "{{ [item | split('/') | last] + resource_id_list_split | default([]) }}" + loop: "{{ resource_id_list }}" + + - name: Count resource_id + ansible.builtin.set_fact: + number_of_resource_id: "{{ resource_id_list_split | length }}" + + - name: Performing Operation 'On' without resource_id when iDRAC has secondary resource_id + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + resource_id: "{{ null | default(omit) }}" + when: number_of_resource_id > '1' + + - name: Asserting after performing opeartion without resource_id when iDRAC has secondary resource_id + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Multiple devices exists in the system, but option 'resource_id' is not specified." + when: number_of_resource_id > '1' + + - name: Performing Operation 'On' with valid secondary resource_id + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: 'On' + resource_id: "{{ resource_id_list[1] }}" + when: number_of_resource_id > '1' + + - name: Asserting after performing opeartion with valid secondary resource_id + ansible.builtin.assert: + that: |- + ( idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'On'." ) + or + ( idrac_server_powerstate_out.msg == "The device is already powered on." ) + when: number_of_resource_id > '1' diff --git a/roles/idrac_server_powerstate/molecule/default/molecule.yml b/roles/idrac_server_powerstate/molecule/default/molecule.yml new file mode 100644 index 000000000..5feaf736f --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/default/molecule.yml @@ -0,0 +1,10 @@ +scenario: + test_sequence: + - dependency + - lint + - destroy + - syntax + - create + - converge + - cleanup + - destroy diff --git a/roles/idrac_server_powerstate/molecule/forceoff/converge.yml b/roles/idrac_server_powerstate/molecule/forceoff/converge.yml new file mode 100644 index 000000000..505c4e59a --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/forceoff/converge.yml @@ -0,0 +1,74 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing ForceOff on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "ForceOff" + resource_id: "System.Embedded.1" + + - name: Asserting ForceOff in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing ForceOff operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "Off" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + + - name: Asserting ForceOff + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'ForceOff'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + + - name: Asserting 'ForceOff' in idempotence mode + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "The device is already powered off." + when: not ansible_check_mode and not idrac_server_powerstate_out.changed diff --git a/roles/idrac_server_powerstate/molecule/forceoff/molecule.yml b/roles/idrac_server_powerstate/molecule/forceoff/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/forcerestart/converge.yml b/roles/idrac_server_powerstate/molecule/forcerestart/converge.yml new file mode 100644 index 000000000..61de7631f --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/forcerestart/converge.yml @@ -0,0 +1,83 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing ForceRestart on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "ForceRestart" + resource_id: "System.Embedded.1" + tags: molecule-idempotence-notest + + - name: Asserting ForceRestart in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: "Waiting after performing ForceRestart operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing ForceRestart operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: "Accept=application/json" + register: current_powerstate + until: current_powerstate.json.PowerState == "On" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + tags: molecule-idempotence-notest + + - name: Asserting ForceRestart + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'ForceRestart'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest diff --git a/roles/idrac_server_powerstate/molecule/forcerestart/molecule.yml b/roles/idrac_server_powerstate/molecule/forcerestart/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/gracefulrestart/converge.yml b/roles/idrac_server_powerstate/molecule/gracefulrestart/converge.yml new file mode 100644 index 000000000..7ddede847 --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/gracefulrestart/converge.yml @@ -0,0 +1,83 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing ForceRestart on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "GracefulRestart" + resource_id: "System.Embedded.1" + tags: molecule-idempotence-notest + + - name: Asserting GracefulRestart in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: "Waiting after performing GracefulRestart operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing GracefulRestart operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "On" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + tags: molecule-idempotence-notest + + - name: Asserting GracefulRestart + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'GracefulRestart'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest diff --git a/roles/idrac_server_powerstate/molecule/gracefulrestart/molecule.yml b/roles/idrac_server_powerstate/molecule/gracefulrestart/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/gracefulshutdown/converge.yml b/roles/idrac_server_powerstate/molecule/gracefulshutdown/converge.yml new file mode 100644 index 000000000..377f458ed --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/gracefulshutdown/converge.yml @@ -0,0 +1,68 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing GracefulShutdown on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "GracefulShutdown" + resource_id: "System.Embedded.1" + + - name: Asserting GracefulShutdown in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing GracefulShutdown operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "Off" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + + - name: Asserting GracefulShutdown + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'GracefulShutdown'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed diff --git a/roles/idrac_server_powerstate/molecule/gracefulshutdown/molecule.yml b/roles/idrac_server_powerstate/molecule/gracefulshutdown/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/nmi/converge.yml b/roles/idrac_server_powerstate/molecule/nmi/converge.yml new file mode 100644 index 000000000..5b03c855c --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/nmi/converge.yml @@ -0,0 +1,83 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing Nmi on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "Nmi" + resource_id: "System.Embedded.1" + tags: molecule-idempotence-notest + + - name: Asserting Nmi in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: "Waiting after performing Nmi operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing Nmi operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "On" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + tags: molecule-idempotence-notest + + - name: Asserting Nmi + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'Nmi'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest diff --git a/roles/idrac_server_powerstate/molecule/nmi/molecule.yml b/roles/idrac_server_powerstate/molecule/nmi/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/on/converge.yml b/roles/idrac_server_powerstate/molecule/on/converge.yml new file mode 100644 index 000000000..d67ea52ec --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/on/converge.yml @@ -0,0 +1,70 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power Off + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "ForceOff" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing Power On operation the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + + - name: Asserting On in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + + - name: "Waiting after performing On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + + - name: Fetching iDRAC server powerstate after performing On operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "On" + retries: 10 + delay: 30 + when: not ansible_check_mode + no_log: true + + - name: Asserting 'On' in normal mode + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'On'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + + - name: Asserting 'On' in idempotence mode + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "The device is already powered on." + when: not ansible_check_mode and not idrac_server_powerstate_out.changed diff --git a/roles/idrac_server_powerstate/molecule/on/molecule.yml b/roles/idrac_server_powerstate/molecule/on/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/powercycle/converge.yml b/roles/idrac_server_powerstate/molecule/powercycle/converge.yml new file mode 100644 index 000000000..5e1b751b3 --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/powercycle/converge.yml @@ -0,0 +1,83 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Pre-requisite - Server is Power On + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "On" + resource_id: "System.Embedded.1" + check_mode: false + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: "Waiting after performing Power On operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: idrac_server_powerstate_out.changed # noqa: no-handler + check_mode: false + tags: molecule-idempotence-notest + + - name: Performing PowerCycle on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "PowerCycle" + resource_id: "System.Embedded.1" + tags: molecule-idempotence-notest + + - name: Asserting PowerCycle in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: "Waiting after performing PowerCycle operation" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing PowerCycle operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + until: current_powerstate.json.PowerState == "On" + retries: 10 + delay: 30 + when: not ansible_check_mode and idrac_server_powerstate_out.changed + no_log: true + tags: molecule-idempotence-notest + + - name: Asserting PowerCycle + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'PowerCycle'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest diff --git a/roles/idrac_server_powerstate/molecule/powercycle/molecule.yml b/roles/idrac_server_powerstate/molecule/powercycle/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/molecule/pushpowerbutton/converge.yml b/roles/idrac_server_powerstate/molecule/pushpowerbutton/converge.yml new file mode 100644 index 000000000..5d466769c --- /dev/null +++ b/roles/idrac_server_powerstate/molecule/pushpowerbutton/converge.yml @@ -0,0 +1,52 @@ +--- +- name: Converge + hosts: all + gather_facts: false + tasks: + - name: Performing PushPowerButton on the iDRAC device + ansible.builtin.import_role: + name: idrac_server_powerstate + vars: + hostname: "{{ lookup('env', 'IDRAC_IP') }}" + username: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + reset_type: "PushPowerButton" + resource_id: "System.Embedded.1" + tags: molecule-idempotence-notest + + - name: Fetching iDRAC server powerstate after performing PushPowerButton operation + ansible.builtin.uri: + url: "https://{{ lookup('env', 'IDRAC_IP') }}:{{ https_port }}/redfish/v1/Systems/System.Embedded.1" + user: "{{ lookup('env', 'IDRAC_USER') }}" + password: "{{ lookup('env', 'IDRAC_PASSWORD') }}" + validate_certs: false + headers: 'Accept=application/json' + register: current_powerstate + no_log: true + tags: molecule-idempotence-notest + + - name: Fetching idrac_server_powerstate_wait_seconds from molecule env variable + ansible.builtin.set_fact: + wait_time: "{{ lookup('env', 'idrac_server_powerstate_wait_seconds', default=300) }}" + when: not ansible_check_mode and current_powerstate.json.PowerState == "On" + tags: molecule-idempotence-notest + + - name: "Waiting after performing PushPowerButton operation, Server is Powering On" + ansible.builtin.pause: + seconds: "{{ wait_time }}" + when: not ansible_check_mode and current_powerstate.json.PowerState == "On" + tags: molecule-idempotence-notest + + - name: Asserting PushPowerButton in check mode + ansible.builtin.assert: + that: idrac_server_powerstate_out.msg == "Changes found to be applied." + when: ansible_check_mode + tags: molecule-idempotence-notest + + - name: Asserting PushPowerButton in normal mode + ansible.builtin.assert: + that: + - idrac_server_powerstate_out.msg == "Successfully performed the reset type operation 'PushPowerButton'." + when: not ansible_check_mode and idrac_server_powerstate_out.changed + tags: molecule-idempotence-notest diff --git a/roles/idrac_server_powerstate/molecule/pushpowerbutton/molecule.yml b/roles/idrac_server_powerstate/molecule/pushpowerbutton/molecule.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/tasks/init.yml b/roles/idrac_server_powerstate/tasks/init.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/idrac_server_powerstate/tasks/main.yml b/roles/idrac_server_powerstate/tasks/main.yml new file mode 100644 index 000000000..5e7ac1aac --- /dev/null +++ b/roles/idrac_server_powerstate/tasks/main.yml @@ -0,0 +1,16 @@ +--- +# tasks file for idrac_server_powerstate +- name: Setting up parameters + ansible.builtin.set_fact: + baseuri: "{{ hostname }}:{{ https_port }}" + +- name: "Performing the operation on iDRAC server: {{ reset_type }}" + dellemc.openmanage.redfish_powerstate: + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + reset_type: "{{ reset_type }}" + validate_certs: "{{ validate_certs }}" + resource_id: "{{ resource_id | default(omit) }}" + register: idrac_server_powerstate_out + delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}" diff --git a/roles/idrac_server_powerstate/tests/inventory b/roles/idrac_server_powerstate/tests/inventory new file mode 100644 index 000000000..878877b07 --- /dev/null +++ b/roles/idrac_server_powerstate/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/idrac_server_powerstate/tests/test.yml b/roles/idrac_server_powerstate/tests/test.yml new file mode 100644 index 000000000..89d986b52 --- /dev/null +++ b/roles/idrac_server_powerstate/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: Executing iDRAC powercycle control role + hosts: localhost + remote_user: root + roles: + - idrac_server_powerstate diff --git a/roles/idrac_server_powerstate/vars/main.yml b/roles/idrac_server_powerstate/vars/main.yml new file mode 100644 index 000000000..192207283 --- /dev/null +++ b/roles/idrac_server_powerstate/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for idrac_server_powerstate diff --git a/roles/molecule.yml b/roles/molecule.yml new file mode 100644 index 000000000..c914e804e --- /dev/null +++ b/roles/molecule.yml @@ -0,0 +1,36 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: centos + image: quay.io/centos/centos:stream8 + pre_build_image: true +provisioner: + name: ansible + env: + RUNON: "" + idrac_server_powerstate_wait_seconds: "180" +verifier: + name: ansible +lint: | + set -e + yamllint . + ansible-lint . +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - prepare + - check + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/tests/unit/plugins/modules/conftest.py b/tests/unit/plugins/modules/conftest.py index 1ae4b0ea9..30096b471 100644 --- a/tests/unit/plugins/modules/conftest.py +++ b/tests/unit/plugins/modules/conftest.py @@ -16,7 +16,7 @@ import pytest from ansible.module_utils import basic -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.utils import set_module_args, exit_json, \ +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.utils import exit_json, \ fail_json, AnsibleFailJson, AnsibleExitJson from mock import MagicMock diff --git a/tests/unit/plugins/modules/test_dellemc_configure_idrac_eventing.py b/tests/unit/plugins/modules/test_dellemc_configure_idrac_eventing.py index 590952b1a..777b8e1b3 100644 --- a/tests/unit/plugins/modules/test_dellemc_configure_idrac_eventing.py +++ b/tests/unit/plugins/modules/test_dellemc_configure_idrac_eventing.py @@ -14,8 +14,8 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_configure_idrac_eventing -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock, PropertyMock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock, PropertyMock from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_dellemc_configure_idrac_services.py b/tests/unit/plugins/modules/test_dellemc_configure_idrac_services.py index d9d4378d1..16388a29c 100644 --- a/tests/unit/plugins/modules/test_dellemc_configure_idrac_services.py +++ b/tests/unit/plugins/modules/test_dellemc_configure_idrac_services.py @@ -14,8 +14,8 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_configure_idrac_services -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_dellemc_get_firmware_inventory.py b/tests/unit/plugins/modules/test_dellemc_get_firmware_inventory.py index faa724e70..a324585da 100644 --- a/tests/unit/plugins/modules/test_dellemc_get_firmware_inventory.py +++ b/tests/unit/plugins/modules/test_dellemc_get_firmware_inventory.py @@ -14,7 +14,7 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_get_firmware_inventory -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock, PropertyMock from pytest import importorskip diff --git a/tests/unit/plugins/modules/test_dellemc_get_system_inventory.py b/tests/unit/plugins/modules/test_dellemc_get_system_inventory.py index 456f5f25b..6c5adf806 100644 --- a/tests/unit/plugins/modules/test_dellemc_get_system_inventory.py +++ b/tests/unit/plugins/modules/test_dellemc_get_system_inventory.py @@ -14,7 +14,7 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_get_system_inventory -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock, Mock from pytest import importorskip diff --git a/tests/unit/plugins/modules/test_dellemc_idrac_lc_attributes.py b/tests/unit/plugins/modules/test_dellemc_idrac_lc_attributes.py index ec42c718d..581e65a07 100644 --- a/tests/unit/plugins/modules/test_dellemc_idrac_lc_attributes.py +++ b/tests/unit/plugins/modules/test_dellemc_idrac_lc_attributes.py @@ -14,8 +14,8 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_idrac_lc_attributes -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_dellemc_idrac_storage_volume.py b/tests/unit/plugins/modules/test_dellemc_idrac_storage_volume.py index a471b04c0..1d4f36238 100644 --- a/tests/unit/plugins/modules/test_dellemc_idrac_storage_volume.py +++ b/tests/unit/plugins/modules/test_dellemc_idrac_storage_volume.py @@ -15,8 +15,8 @@ import pytest import os from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_idrac_storage_volume -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_dellemc_system_lockdown_mode.py b/tests/unit/plugins/modules/test_dellemc_system_lockdown_mode.py index 18754253d..b55e5eafe 100644 --- a/tests/unit/plugins/modules/test_dellemc_system_lockdown_mode.py +++ b/tests/unit/plugins/modules/test_dellemc_system_lockdown_mode.py @@ -14,8 +14,8 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import dellemc_system_lockdown_mode -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_idrac_attributes.py b/tests/unit/plugins/modules/test_idrac_attributes.py index 862e16177..64e246765 100644 --- a/tests/unit/plugins/modules/test_idrac_attributes.py +++ b/tests/unit/plugins/modules/test_idrac_attributes.py @@ -13,14 +13,11 @@ __metaclass__ = type import json -import os -import tempfile from io import StringIO import pytest from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible_collections.dellemc.openmanage.plugins.modules import idrac_attributes from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock diff --git a/tests/unit/plugins/modules/test_idrac_boot.py b/tests/unit/plugins/modules/test_idrac_boot.py index 3cb4e186e..6c0c63b83 100644 --- a/tests/unit/plugins/modules/test_idrac_boot.py +++ b/tests/unit/plugins/modules/test_idrac_boot.py @@ -15,9 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_boot -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock -from mock import PropertyMock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from io import StringIO from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError diff --git a/tests/unit/plugins/modules/test_idrac_firmware.py b/tests/unit/plugins/modules/test_idrac_firmware.py index 6db1f727d..20f4eb436 100644 --- a/tests/unit/plugins/modules/test_idrac_firmware.py +++ b/tests/unit/plugins/modules/test_idrac_firmware.py @@ -15,13 +15,13 @@ import json import pytest from ansible_collections.dellemc.openmanage.plugins.modules import idrac_firmware -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from mock import MagicMock, patch, Mock +from mock import MagicMock, Mock from io import StringIO from ansible.module_utils._text import to_text -from ansible.module_utils.six.moves.urllib.parse import urlparse, ParseResult +from ansible.module_utils.six.moves.urllib.parse import ParseResult from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_idrac_firmware_info.py b/tests/unit/plugins/modules/test_idrac_firmware_info.py index 8bea5ec02..60c77732b 100644 --- a/tests/unit/plugins/modules/test_idrac_firmware_info.py +++ b/tests/unit/plugins/modules/test_idrac_firmware_info.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_firmware_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock, PropertyMock from pytest import importorskip from ansible.module_utils.urls import ConnectionError, SSLValidationError diff --git a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py index 9f09105f9..d36524a76 100644 --- a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py +++ b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py @@ -14,7 +14,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_lifecycle_controller_job_status_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock, PropertyMock from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError diff --git a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_jobs.py b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_jobs.py index cfc813b82..841f768fe 100644 --- a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_jobs.py +++ b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_jobs.py @@ -15,9 +15,9 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_lifecycle_controller_jobs -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import SSLValidationError from mock import MagicMock, PropertyMock from io import StringIO from ansible.module_utils._text import to_text diff --git a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_logs.py b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_logs.py index df73aa217..a5dd7fdf5 100644 --- a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_logs.py +++ b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_logs.py @@ -14,8 +14,8 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_lifecycle_controller_logs -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO diff --git a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_status_info.py b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_status_info.py index ba69f2a5f..5edcb4c23 100644 --- a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_status_info.py +++ b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_status_info.py @@ -14,8 +14,8 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_lifecycle_controller_status_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError from mock import PropertyMock diff --git a/tests/unit/plugins/modules/test_idrac_network.py b/tests/unit/plugins/modules/test_idrac_network.py index 745ddcdd1..905002f19 100644 --- a/tests/unit/plugins/modules/test_idrac_network.py +++ b/tests/unit/plugins/modules/test_idrac_network.py @@ -15,8 +15,8 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_network -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from io import StringIO from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError diff --git a/tests/unit/plugins/modules/test_idrac_os_deployment.py b/tests/unit/plugins/modules/test_idrac_os_deployment.py index e18dc7ad0..0ca5869cd 100644 --- a/tests/unit/plugins/modules/test_idrac_os_deployment.py +++ b/tests/unit/plugins/modules/test_idrac_os_deployment.py @@ -14,10 +14,9 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import idrac_os_deployment -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.utils import set_module_args, exit_json, \ - fail_json, AnsibleFailJson, AnsibleExitJson +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.utils import set_module_args from pytest import importorskip importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_idrac_redfish_storage_controller.py b/tests/unit/plugins/modules/test_idrac_redfish_storage_controller.py index 7da0a050a..50f8bfbf5 100644 --- a/tests/unit/plugins/modules/test_idrac_redfish_storage_controller.py +++ b/tests/unit/plugins/modules/test_idrac_redfish_storage_controller.py @@ -15,12 +15,11 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_redfish_storage_controller -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO from ansible.module_utils._text import to_text -from ansible.module_utils.urls import urllib_error MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' diff --git a/tests/unit/plugins/modules/test_idrac_reset.py b/tests/unit/plugins/modules/test_idrac_reset.py index a0ec111f0..7235b9ab6 100644 --- a/tests/unit/plugins/modules/test_idrac_reset.py +++ b/tests/unit/plugins/modules/test_idrac_reset.py @@ -14,10 +14,10 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_reset -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from mock import MagicMock, patch, Mock +from mock import MagicMock, Mock from io import StringIO from ansible.module_utils._text import to_text diff --git a/tests/unit/plugins/modules/test_idrac_server_config_profile.py b/tests/unit/plugins/modules/test_idrac_server_config_profile.py index 60706e6cf..476a71a65 100644 --- a/tests/unit/plugins/modules/test_idrac_server_config_profile.py +++ b/tests/unit/plugins/modules/test_idrac_server_config_profile.py @@ -14,11 +14,10 @@ import pytest import sys from ansible_collections.dellemc.openmanage.plugins.modules import idrac_server_config_profile -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants,\ - AnsibleExitJson -from mock import MagicMock, patch, Mock, mock_open +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, patch, mock_open from pytest import importorskip -from ansible.module_utils.six.moves.urllib.parse import urlparse, ParseResult +from ansible.module_utils.six.moves.urllib.parse import ParseResult MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' importorskip("omsdk.sdkfile") diff --git a/tests/unit/plugins/modules/test_idrac_syslog.py b/tests/unit/plugins/modules/test_idrac_syslog.py index ec63c746d..451496fab 100644 --- a/tests/unit/plugins/modules/test_idrac_syslog.py +++ b/tests/unit/plugins/modules/test_idrac_syslog.py @@ -17,8 +17,8 @@ from ansible_collections.dellemc.openmanage.plugins.modules import idrac_syslog from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock from io import StringIO from ansible.module_utils._text import to_text from pytest import importorskip diff --git a/tests/unit/plugins/modules/test_idrac_system_info.py b/tests/unit/plugins/modules/test_idrac_system_info.py index 25af1f7de..b18cb94c7 100644 --- a/tests/unit/plugins/modules/test_idrac_system_info.py +++ b/tests/unit/plugins/modules/test_idrac_system_info.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_system_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock, Mock from pytest import importorskip from ansible.module_utils.urls import ConnectionError, SSLValidationError diff --git a/tests/unit/plugins/modules/test_idrac_timezone_ntp.py b/tests/unit/plugins/modules/test_idrac_timezone_ntp.py index c4b9bfe72..ccbc6a2dc 100644 --- a/tests/unit/plugins/modules/test_idrac_timezone_ntp.py +++ b/tests/unit/plugins/modules/test_idrac_timezone_ntp.py @@ -14,8 +14,8 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_timezone_ntp -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock, PropertyMock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock, Mock from io import StringIO from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError diff --git a/tests/unit/plugins/modules/test_idrac_user.py b/tests/unit/plugins/modules/test_idrac_user.py index 708045324..2208e988e 100644 --- a/tests/unit/plugins/modules/test_idrac_user.py +++ b/tests/unit/plugins/modules/test_idrac_user.py @@ -16,8 +16,8 @@ from ansible_collections.dellemc.openmanage.plugins.modules import idrac_user from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock from ansible.module_utils._text import to_text from io import StringIO diff --git a/tests/unit/plugins/modules/test_idrac_user_info.py b/tests/unit/plugins/modules/test_idrac_user_info.py index ecaa85d6d..5970d0388 100644 --- a/tests/unit/plugins/modules/test_idrac_user_info.py +++ b/tests/unit/plugins/modules/test_idrac_user_info.py @@ -16,8 +16,8 @@ from ansible_collections.dellemc.openmanage.plugins.modules import idrac_user_info from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule +from mock import MagicMock from ansible.module_utils._text import to_text from io import StringIO diff --git a/tests/unit/plugins/modules/test_idrac_virtual_media.py b/tests/unit/plugins/modules/test_idrac_virtual_media.py index 94e620f3e..63e879f17 100644 --- a/tests/unit/plugins/modules/test_idrac_virtual_media.py +++ b/tests/unit/plugins/modules/test_idrac_virtual_media.py @@ -15,9 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import idrac_virtual_media -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock -from mock import PropertyMock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from io import StringIO from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError diff --git a/tests/unit/plugins/modules/test_ome_application_alerts_smtp.py b/tests/unit/plugins/modules/test_ome_application_alerts_smtp.py index aaee2d027..506f3877e 100644 --- a/tests/unit/plugins/modules/test_ome_application_alerts_smtp.py +++ b/tests/unit/plugins/modules/test_ome_application_alerts_smtp.py @@ -18,10 +18,9 @@ import pytest from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import SSLValidationError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_alerts_smtp -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule SUCCESS_MSG = "Successfully updated the SMTP settings." SMTP_URL = "AlertService/AlertDestinations/SMTPConfiguration" diff --git a/tests/unit/plugins/modules/test_ome_application_certificate.py b/tests/unit/plugins/modules/test_ome_application_certificate.py index cb52870b6..1e6d2bf9c 100644 --- a/tests/unit/plugins/modules/test_ome_application_certificate.py +++ b/tests/unit/plugins/modules/test_ome_application_certificate.py @@ -21,7 +21,7 @@ from ansible.module_utils._text import to_text from ssl import SSLError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_certificate -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' diff --git a/tests/unit/plugins/modules/test_ome_application_console_preferences.py b/tests/unit/plugins/modules/test_ome_application_console_preferences.py index 8fcf2de39..5b7414e0c 100644 --- a/tests/unit/plugins/modules/test_ome_application_console_preferences.py +++ b/tests/unit/plugins/modules/test_ome_application_console_preferences.py @@ -18,11 +18,9 @@ import pytest from ansible.module_utils._text import to_text from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ssl import SSLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import SSLValidationError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_console_preferences -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule SUCCESS_MSG = "Successfully updated the Console Preferences settings." SETTINGS_URL = "ApplicationService/Settings" diff --git a/tests/unit/plugins/modules/test_ome_application_network_address.py b/tests/unit/plugins/modules/test_ome_application_network_address.py index 45c768d26..416a2ba1d 100644 --- a/tests/unit/plugins/modules/test_ome_application_network_address.py +++ b/tests/unit/plugins/modules/test_ome_application_network_address.py @@ -19,7 +19,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_network_address -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' diff --git a/tests/unit/plugins/modules/test_ome_application_network_proxy.py b/tests/unit/plugins/modules/test_ome_application_network_proxy.py index 77e1c3df7..285b28585 100644 --- a/tests/unit/plugins/modules/test_ome_application_network_proxy.py +++ b/tests/unit/plugins/modules/test_ome_application_network_proxy.py @@ -21,7 +21,7 @@ from ansible.module_utils._text import to_text from ssl import SSLError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_network_proxy -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' CHECK_MODE_CHANGE_FOUND_MSG = "Changes found to be applied." diff --git a/tests/unit/plugins/modules/test_ome_application_network_settings.py b/tests/unit/plugins/modules/test_ome_application_network_settings.py index 1377c275d..ddfabbb9c 100644 --- a/tests/unit/plugins/modules/test_ome_application_network_settings.py +++ b/tests/unit/plugins/modules/test_ome_application_network_settings.py @@ -16,12 +16,11 @@ import pytest from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError +from ansible.module_utils.urls import SSLValidationError from io import StringIO from ansible.module_utils._text import to_text -from ssl import SSLError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_network_settings -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule SUCCESS_MSG = "Successfully updated the session timeout settings." NO_CHANGES = "No changes found to be applied." diff --git a/tests/unit/plugins/modules/test_ome_application_network_time.py b/tests/unit/plugins/modules/test_ome_application_network_time.py index 62aa621b6..4ffa69415 100644 --- a/tests/unit/plugins/modules/test_ome_application_network_time.py +++ b/tests/unit/plugins/modules/test_ome_application_network_time.py @@ -21,7 +21,7 @@ from ansible.module_utils._text import to_text from ssl import SSLError from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_network_time -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' diff --git a/tests/unit/plugins/modules/test_ome_application_network_webserver.py b/tests/unit/plugins/modules/test_ome_application_network_webserver.py index a9a981a4f..7e65dbc7d 100644 --- a/tests/unit/plugins/modules/test_ome_application_network_webserver.py +++ b/tests/unit/plugins/modules/test_ome_application_network_webserver.py @@ -20,7 +20,7 @@ from io import StringIO from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_application_network_webserver -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' diff --git a/tests/unit/plugins/modules/test_ome_chassis_slots.py b/tests/unit/plugins/modules/test_ome_chassis_slots.py index 23cf16b8a..e5294d928 100644 --- a/tests/unit/plugins/modules/test_ome_chassis_slots.py +++ b/tests/unit/plugins/modules/test_ome_chassis_slots.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_chassis_slots -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule DEVICE_REPEATED = "Duplicate device entry found for devices with identifiers {0}." INVALID_SLOT_DEVICE = "Unable to rename one or more slots because either the specified device is invalid or slots " \ diff --git a/tests/unit/plugins/modules/test_ome_configuration_compliance_info.py b/tests/unit/plugins/modules/test_ome_configuration_compliance_info.py index 950b19e08..685e73a03 100644 --- a/tests/unit/plugins/modules/test_ome_configuration_compliance_info.py +++ b/tests/unit/plugins/modules/test_ome_configuration_compliance_info.py @@ -13,15 +13,8 @@ __metaclass__ = type import pytest -import json -from ssl import SSLError from ansible_collections.dellemc.openmanage.plugins.modules import ome_configuration_compliance_info -from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError -from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException -from io import StringIO -from ansible.module_utils._text import to_text +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_configuration_compliance_info.' diff --git a/tests/unit/plugins/modules/test_ome_device_group.py b/tests/unit/plugins/modules/test_ome_device_group.py index f92a0abe5..1a777a0a1 100644 --- a/tests/unit/plugins/modules/test_ome_device_group.py +++ b/tests/unit/plugins/modules/test_ome_device_group.py @@ -17,8 +17,7 @@ from ssl import SSLError from io import StringIO from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_group -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text @@ -32,7 +31,6 @@ IP_NOT_EXISTS = "The IP addresses provided do not exist in OpenManage Enterprise." try: from netaddr import IPAddress, IPNetwork, IPRange - from netaddr.core import AddrFormatError HAS_NETADDR = True except ImportError: diff --git a/tests/unit/plugins/modules/test_ome_device_local_access_configuration.py b/tests/unit/plugins/modules/test_ome_device_local_access_configuration.py index f17fb65d6..f989a29af 100644 --- a/tests/unit/plugins/modules/test_ome_device_local_access_configuration.py +++ b/tests/unit/plugins/modules/test_ome_device_local_access_configuration.py @@ -20,8 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_local_access_configuration -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_local_access_configuration.' diff --git a/tests/unit/plugins/modules/test_ome_device_location.py b/tests/unit/plugins/modules/test_ome_device_location.py index 6f7952710..cb3df076b 100644 --- a/tests/unit/plugins/modules/test_ome_device_location.py +++ b/tests/unit/plugins/modules/test_ome_device_location.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_location -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_location.' diff --git a/tests/unit/plugins/modules/test_ome_device_network_services.py b/tests/unit/plugins/modules/test_ome_device_network_services.py index e6972dccc..ed8c93f08 100644 --- a/tests/unit/plugins/modules/test_ome_device_network_services.py +++ b/tests/unit/plugins/modules/test_ome_device_network_services.py @@ -13,7 +13,6 @@ __metaclass__ = type import json -import pdb import pytest from ssl import SSLError @@ -22,8 +21,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_network_services -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_network_services.' diff --git a/tests/unit/plugins/modules/test_ome_device_power_settings.py b/tests/unit/plugins/modules/test_ome_device_power_settings.py index d3b9a2c86..8f72865c4 100644 --- a/tests/unit/plugins/modules/test_ome_device_power_settings.py +++ b/tests/unit/plugins/modules/test_ome_device_power_settings.py @@ -20,8 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_power_settings -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants -from mock import MagicMock, patch, Mock +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_power_settings.' diff --git a/tests/unit/plugins/modules/test_ome_device_quick_deploy.py b/tests/unit/plugins/modules/test_ome_device_quick_deploy.py index bc36e21fe..8bae41c4f 100644 --- a/tests/unit/plugins/modules/test_ome_device_quick_deploy.py +++ b/tests/unit/plugins/modules/test_ome_device_quick_deploy.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_quick_deploy -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_quick_deploy.' diff --git a/tests/unit/plugins/modules/test_ome_diagnostics.py b/tests/unit/plugins/modules/test_ome_diagnostics.py index f42e44352..f98138e41 100644 --- a/tests/unit/plugins/modules/test_ome_diagnostics.py +++ b/tests/unit/plugins/modules/test_ome_diagnostics.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_diagnostics -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_diagnostics.' diff --git a/tests/unit/plugins/modules/test_ome_discovery.py b/tests/unit/plugins/modules/test_ome_discovery.py index f3f3743e2..e754ffe77 100644 --- a/tests/unit/plugins/modules/test_ome_discovery.py +++ b/tests/unit/plugins/modules/test_ome_discovery.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_discovery -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_discovery.' NO_CHANGES_MSG = "No changes found to be applied." diff --git a/tests/unit/plugins/modules/test_ome_domain_user_groups.py b/tests/unit/plugins/modules/test_ome_domain_user_groups.py index 7d37725ad..20616d712 100644 --- a/tests/unit/plugins/modules/test_ome_domain_user_groups.py +++ b/tests/unit/plugins/modules/test_ome_domain_user_groups.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_domain_user_groups -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_domain_user_groups.' NO_CHANGES_MSG = "No changes found to be applied." diff --git a/tests/unit/plugins/modules/test_ome_firmware_baseline_info.py b/tests/unit/plugins/modules/test_ome_firmware_baseline_info.py index f82731a5f..19f2f70f3 100644 --- a/tests/unit/plugins/modules/test_ome_firmware_baseline_info.py +++ b/tests/unit/plugins/modules/test_ome_firmware_baseline_info.py @@ -18,7 +18,7 @@ from ansible_collections.dellemc.openmanage.plugins.modules import ome_firmware_baseline_info from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from io import StringIO from ansible.module_utils._text import to_text diff --git a/tests/unit/plugins/modules/test_ome_groups.py b/tests/unit/plugins/modules/test_ome_groups.py index e334eb08e..4e44bfd05 100644 --- a/tests/unit/plugins/modules/test_ome_groups.py +++ b/tests/unit/plugins/modules/test_ome_groups.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_groups -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MULTIPLE_GROUPS_MSG = "Provide only one unique device group when state is present." NONEXIST_GROUP_ID = "A device group with the provided ID does not exist." diff --git a/tests/unit/plugins/modules/test_ome_identity_pool.py b/tests/unit/plugins/modules/test_ome_identity_pool.py index bde458ff2..025c993e5 100644 --- a/tests/unit/plugins/modules/test_ome_identity_pool.py +++ b/tests/unit/plugins/modules/test_ome_identity_pool.py @@ -14,7 +14,7 @@ import pytest from ansible_collections.dellemc.openmanage.plugins.modules import ome_identity_pool -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from ssl import SSLError diff --git a/tests/unit/plugins/modules/test_ome_job_info.py b/tests/unit/plugins/modules/test_ome_job_info.py index bf304beb9..4843a3e8a 100644 --- a/tests/unit/plugins/modules/test_ome_job_info.py +++ b/tests/unit/plugins/modules/test_ome_job_info.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import ome_job_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO diff --git a/tests/unit/plugins/modules/test_ome_network_port_breakout.py b/tests/unit/plugins/modules/test_ome_network_port_breakout.py index 8c13f9333..990794cdf 100644 --- a/tests/unit/plugins/modules/test_ome_network_port_breakout.py +++ b/tests/unit/plugins/modules/test_ome_network_port_breakout.py @@ -17,8 +17,7 @@ from ansible_collections.dellemc.openmanage.plugins.modules import ome_network_port_breakout from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from io import StringIO from ansible.module_utils._text import to_text diff --git a/tests/unit/plugins/modules/test_ome_network_vlan.py b/tests/unit/plugins/modules/test_ome_network_vlan.py index 5f977a36a..5d56fe08e 100644 --- a/tests/unit/plugins/modules/test_ome_network_vlan.py +++ b/tests/unit/plugins/modules/test_ome_network_vlan.py @@ -19,7 +19,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_network_vlan -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_network_vlan.' diff --git a/tests/unit/plugins/modules/test_ome_network_vlan_info.py b/tests/unit/plugins/modules/test_ome_network_vlan_info.py index 391488237..846ac06c1 100644 --- a/tests/unit/plugins/modules/test_ome_network_vlan_info.py +++ b/tests/unit/plugins/modules/test_ome_network_vlan_info.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import ome_network_vlan_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO diff --git a/tests/unit/plugins/modules/test_ome_server_interface_profile_info.py b/tests/unit/plugins/modules/test_ome_server_interface_profile_info.py index a83cb9e0b..e3ab52271 100644 --- a/tests/unit/plugins/modules/test_ome_server_interface_profile_info.py +++ b/tests/unit/plugins/modules/test_ome_server_interface_profile_info.py @@ -20,7 +20,7 @@ from ansible.module_utils.urls import ConnectionError, SSLValidationError from ansible.module_utils._text import to_text from ansible_collections.dellemc.openmanage.plugins.modules import ome_server_interface_profile_info -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_server_interface_profile_info.' diff --git a/tests/unit/plugins/modules/test_ome_template_identity_pool.py b/tests/unit/plugins/modules/test_ome_template_identity_pool.py index 2407eb827..bad00f68d 100644 --- a/tests/unit/plugins/modules/test_ome_template_identity_pool.py +++ b/tests/unit/plugins/modules/test_ome_template_identity_pool.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import ome_template_identity_pool -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from ssl import SSLError diff --git a/tests/unit/plugins/modules/test_ome_user.py b/tests/unit/plugins/modules/test_ome_user.py index 18c570a97..44981bb38 100644 --- a/tests/unit/plugins/modules/test_ome_user.py +++ b/tests/unit/plugins/modules/test_ome_user.py @@ -17,8 +17,7 @@ from ansible_collections.dellemc.openmanage.plugins.modules import ome_user from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from ansible.module_utils.urls import ConnectionError, SSLValidationError -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \ - AnsibleFailJSonException +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from io import StringIO from ansible.module_utils._text import to_text diff --git a/tests/unit/plugins/modules/test_redfish_firmware.py b/tests/unit/plugins/modules/test_redfish_firmware.py index f8ab03365..ffc8797f2 100644 --- a/tests/unit/plugins/modules/test_redfish_firmware.py +++ b/tests/unit/plugins/modules/test_redfish_firmware.py @@ -17,7 +17,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import redfish_firmware -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from mock import MagicMock from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError diff --git a/tests/unit/plugins/modules/test_redfish_powerstate.py b/tests/unit/plugins/modules/test_redfish_powerstate.py index 1d4ee47e5..91347eced 100644 --- a/tests/unit/plugins/modules/test_redfish_powerstate.py +++ b/tests/unit/plugins/modules/test_redfish_powerstate.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import redfish_powerstate -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO diff --git a/tests/unit/plugins/modules/test_redfish_storage_volume.py b/tests/unit/plugins/modules/test_redfish_storage_volume.py index 9d541fed4..0b73662b4 100644 --- a/tests/unit/plugins/modules/test_redfish_storage_volume.py +++ b/tests/unit/plugins/modules/test_redfish_storage_volume.py @@ -15,7 +15,7 @@ import pytest import json from ansible_collections.dellemc.openmanage.plugins.modules import redfish_storage_volume -from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants +from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.urls import ConnectionError, SSLValidationError from io import StringIO