Browse Source

Issue #427: Configure PowerEdge Servers

Signed-off-by: abhishek-s-a <a_sa@dellteam.com>
Lucas A. Wilson 3 years ago
parent
commit
4e7100c4a8

+ 1 - 0
control_plane/idrac.yml

@@ -16,5 +16,6 @@
 - name: Deploy OS via idrac
   hosts: all
   connection: local
+  gather_facts: false
   roles:
     - provision_idrac

+ 7 - 7
control_plane/inifiniband.yml

@@ -11,11 +11,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
----
 
-- name: Infiniband Configuration
-  hosts: all
-  gather_facts: false
-  connection: local
-  roles:
-    - network_ib
+---
+-  name: Infiniband Configuration
+   hosts: all
+   gather_facts: false
+   connection: local
+   roles:
+    - network_ib

+ 30 - 2
control_plane/input_params/idrac_vars.yml

@@ -23,7 +23,16 @@ idrac_system_profile: "Performance"
 # Boolean value indicating whether OMNIA should perform firmware update or not
 # It takes values "true" or "false" indicating required and not required cases respectively.
 # Default value is "true"
-firmware_update_required: true
+# firmware_update_required should be 'false' now as there is bug in DSU & OMAM modules and firmware updates dependent on that.
+# It will be updated to 'true' once DSU and OMAM fix the bugs
+firmware_update_required: false
+
+# This is the list of poweredge server models
+# The firmware updates will be downloaded only for the below list of models
+# Update the list in the format given below
+# poweredge_model: R640,R740,C4140
+# supported models: C4140,C6420,C6520,R240,R340,R440,R540,R640,R650,R740,R740xd,R740xd2,R750,R750xa,R840,R940,R940xa
+poweredge_model: C6420
 
 #****Security Requirements Configuration****#
 ###Enable the security parameters listed below only if you want to configure the security settings in idrac###
@@ -43,4 +52,23 @@ uefi_secure_boot: "disabled"
 # By default system lockdown will be "disabled"
 # If required it can be "enabled"
 # Make sure system_lockdown is enabled only after OS provisioning is completed
-system_lockdown: "disabled"
+system_lockdown: "disabled"
+
+### Usage: idrac_2fa ###
+
+# Specify whether the two factor authentication to be enabled
+# By default two factor authentication will be "disabled"
+# If required it can be "enabled"
+# [WARNING] Once 2FA is enabled, user has to disable 2FA manually. Other iDRAC playbooks won't run if 2FA is enabled
+# Update 2FA input parameters in idrac_tools_vars.yml if two_factor_authentication is enabled
+# Command to edit idrac_tools_vars.yml: ansible-vault edit idrac_tools_vars.yml --vault-password-file .idrac_vault_key
+two_factor_authentication: "disabled"
+
+### Usage: idrac_ldap ###
+
+# Specify whether the LDAP directory services to be enabled
+# By default LDAP directory services will be disabled
+# If required it can be "enabled"
+# Update 2FA input parameters in idrac_tools_vars.yml if two_factor_authentication is enabled
+# Command to edit idrac_tools_vars.yml: ansible-vault edit idrac_tools_vars.yml --vault-password-file .idrac_vault_key
+ldap_directory_services: "disabled"

+ 0 - 54
control_plane/roles/control_plane_customiso/files/add_nfs_client.yml

@@ -1,54 +0,0 @@
-#  Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
----
-
-- name: Add nfs client entries
-  hosts: localhost
-  connection: local
-  gather_facts: false
-  tasks:
-    - name: Include control_plane_repo vars
-      include_vars: ../../control_plane_repo/vars/main.yml
-
-    - name: Check if idrac inventory file exists
-      stat:
-        path: "../../collect_device_info/files/idrac_inventory"
-      register: provisioned_file_result
-
-    - name: Check {{ exports_file_path }}
-      command: cat {{ exports_file_path }}
-      register: exports_file_check
-      changed_when: false
-      when: provisioned_file_result.stat.exists
-
-    - name: Adding NFS share entries in {{ exports_file_path }}
-      lineinfile:
-        path: "{{ exports_file_path }}"
-        line: "{{ nfs_share_offline_repo }} {{ item }}(rw,sync,no_root_squash)"
-      when:
-        - provisioned_file_result.stat.exists
-        - item not in exports_file_check.stdout
-      loop: "{{ lookup('file', '../../collect_device_info/files/idrac_inventory').splitlines() }}"
-
-    - name: Exporting the shared directories
-      command: /usr/sbin/exportfs -r
-      changed_when: true
-      when: provisioned_file_result.stat.exists
-
-    - name: Copy exports file to custom_iso role
-      copy:
-        src: "{{ exports_file_path }}"
-        dest: "{{ playbook_dir }}/exports"
-        mode: preserve
-      when: provisioned_file_result.stat.exists

+ 1 - 1
control_plane/roles/control_plane_customiso/files/temp_centos7.cfg

@@ -22,7 +22,7 @@ keyboard us
 lang ks_language
 
 # Network information
-network  --bootproto=dhcp --device=ks_nic --onboot=on
+network  --bootproto=dhcp --device=link --onboot=on --activate
 
 # Root password
 rootpw --iscrypted ks_password

+ 8 - 1
control_plane/roles/control_plane_customiso/tasks/check_prerequisites.yml

@@ -43,4 +43,11 @@
     msg: "{{ iso_mount_check_fail_msg }}"
   when: not check_mount_iso.stat.exists
   register: iso_mount_fail
-  tags: install
+  tags: install
+
+- name: Copy management station ip to {{ management_station_ip_file }}
+  lineinfile:
+    path: "{{ role_path }}/../provision_idrac/files/{{ management_station_ip_file }}"
+    line: "{{ mngmnt_network_ip }}"
+    mode: "{{ file_permission }}"
+    create: yes

+ 2 - 15
control_plane/roles/control_plane_customiso/tasks/create_unattended_iso.yml

@@ -15,7 +15,7 @@
 
 - name: Create custom ISO
   command: >-
-    mkisofs -o {{ role_path }}/files/{{ unattended_iso_filename }} -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4
+    mkisofs -o /tmp/{{ unattended_iso_filename }} -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4
     -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -J -R -V "CentOS 7 x86_64"  {{ tmp_iso_dir }}
   changed_when: true
   register: custom_iso_status
@@ -45,20 +45,7 @@
 
 - name: Copy ISO file to nfs share
   copy:
-    src: "{{ role_path }}/files/{{ unattended_iso_filename }}"
+    src: "/tmp/{{ unattended_iso_filename }}"
     dest: "{{ nfs_share_offline_repo }}/{{ unattended_iso_filename }}"
     mode: preserve
-  tags: install
-
-- name: Fetch ansible-playbook location
-  command: whereis ansible-playbook
-  changed_when: false
-  register: ansible_playbook_location
-  tags: install
-
-- name: Schedule task
-  cron:
-    name: "Add idrac IP to nfs exports"
-    minute: "*/10"
-    job: "if ! out=`{{ ansible_playbook_location.stdout.split(' ')[1] }} {{ role_path }}/files/add_nfs_client.yml`; then echo $out >> {{ cron_error_log }}; fi"
   tags: install

+ 8 - 16
control_plane/roles/control_plane_customiso/tasks/edit_iso_config.yml

@@ -13,18 +13,9 @@
 #  limitations under the License.
 ---
 
-- name: Create iso directory
-  file:
-    path: "{{ tmp_iso_dir }}"
-    state: directory
-    mode: "{{ file_permission }}"
-  tags: install
-
-- name: Copy files to tmpiso folder
-  copy:
-    src: "{{ iso_mount_path }}"
-    dest: "{{ tmp_iso_dir }}"
-    mode: preserve
+- name: Copy files to tmp folder
+  command: cp -r {{ iso_mount_path }} /tmp/
+  changed_when: true
   tags: install
 
 - name: Edit isolinux.cfg
@@ -84,11 +75,12 @@
   tags: install
 
 - name: Configure kickstart file - nic
-  replace:
+  lineinfile:
     path: "{{ role_path }}/files/{{ kickstart_file }}"
-    regexp: '^network  --bootproto=dhcp --device=ks_nic --onboot=on'
-    replace: 'network  --bootproto=dhcp --device={{ host_network_nic }} --onboot=on'
+    insertafter: '^network  --bootproto=dhcp --device=link --onboot=on --activate'
+    line: 'network  --bootproto=dhcp --device={{ item }} --onboot=on --activate'
   tags: install
+  with_items: "{{ host_nic }}"
 
 - name: Configure kickstart file - timezone
   replace:
@@ -107,6 +99,6 @@
 - name: Copy kickstart file to iso mount path
   copy:
     src: "{{ role_path }}/files/{{ kickstart_file }}"
-    dest: "/tmp/tmpiso/{{ kickstart_file }}"
+    dest: "{{ tmp_iso_dir }}{{ kickstart_file }}"
     mode: preserve
   tags: install

+ 9 - 2
control_plane/roles/control_plane_customiso/vars/main.yml

@@ -20,14 +20,21 @@ iso_mount_path: /mnt/iso/
 iso_mount_check_fail_msg: "ISO file not mounted. Ensure /mnt/iso path is mounted with centos ISO file."
 
 #Usage: edit_iso_config.yml
-tmp_iso_dir: /tmp/tmpiso/
+tmp_iso_dir: /tmp/iso/
 kickstart_file: centos7.cfg
 file_permission: 0744
 isolinux_cfg_path: isolinux/isolinux.cfg
 grub_cfg_path: EFI/BOOT/grub.cfg
+host_nic:
+ - em1
+ - em2
+ - em3
+ - em4
+ - p4p1
+ - p4p2
 
 #Usage: create_unattended_iso.yml
 unattended_iso_filename: unattended_centos7.iso
 custom_iso_success_msg: "Unattended ISO file created successfully"
 custom_iso_fail_msg: "Unattended ISO file creation failed. Ensure /mnt/iso path is mounted with valid centos minimal ISO file."
-cron_error_log: /var/log/nfs_cron_error.log
+management_station_ip_file: "management_station_ip.txt"

+ 1 - 1
control_plane/roles/control_plane_sm/files/Dockerfile

@@ -6,7 +6,7 @@ RUN dnf install -y epel-release
 
 RUN dnf groupinstall "Infiniband Support" -y
 
-RUN dnf install -y opensm
+RUN dnf install -y opensm-3.3.23
 
 COPY opensm.conf /etc/rdma/opensm.conf
 

+ 24 - 0
control_plane/roles/network_ib/tasks/disable_switch_sm.yml

@@ -0,0 +1,24 @@
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+---
+
+- name: Ensure Subnet Manager is disabled on switch
+  block:
+  - name: Set parameters to disable sm
+    set_fact:
+      sm_config: "no ib sm"
+
+  - name: Disable subnet manager on switch
+    include_tasks: global_config.yml
+    with_items: "{{ sm_config }}"

+ 3 - 0
control_plane/roles/network_ib/tasks/main.yml

@@ -31,6 +31,9 @@
     - name: Configure SNMP
       include_tasks: snmp_config.yml
 
+    - name: Ensure SM is disabled on switch
+      include_tasks: disable_switch_sm.yml
+
     - name: Save running-config to startup-config
       include_tasks: save_config.yml
 

+ 120 - 59
control_plane/roles/provision_idrac/tasks/check_prerequisites.yml

@@ -21,65 +21,49 @@
   include_vars: ../../control_plane_customiso/vars/main.yml
   run_once: true
 
-- name: Check unattended ISO file
+- name: Check {{ management_station_ip_file }} file is present
   stat:
-    path: "{{ role_path }}/../control_plane_customiso/files/{{ unattended_iso_filename }}"
-  register: custom_iso_check
+    path: "{{ role_path }}/files/{{ management_station_ip_file }}"
+  register: ip_file_check
   run_once: true
 
-- name: Custom ISO file not present
-  fail:
-    msg: "{{ custom_iso_check_fail_msg }}"
-  when: not custom_iso_check.stat.exists
-  register: custom_iso_fail
-
-- name: Adding NFS share entries in {{ exports_file_path }}
-  lineinfile:
-    path: "{{ exports_file_path }}"
-    line: "{{ nfs_share_offline_repo }} {{ inventory_hostname }}(rw,sync,no_root_squash)"
-  when: '"awx-" not in hostname.stdout'
-
-- name: Exporting the shared directories
-  command: exportfs -r
-  changed_when: true
-  when: '"awx-" not in hostname.stdout'
+- name: Fetch management station ip from {{ management_station_ip_file }}
+  shell: cat {{ role_path }}/files/{{ management_station_ip_file }}
+  changed_when: false
+  register: fetch_ip
   run_once: true
+  when: ip_file_check.stat.exists
 
-- name: Check nfs exports file present
-  stat:
-    path: "{{ role_path }}/../control_plane_customiso/files/exports"
-  register: nfs_exports_present
-  when: '"awx-" in hostname.stdout'
-  run_once: true
+- name: Missing {{ management_station_ip_file }}
+  fail:
+    msg: "{{ missing_ip_file_fail_msg }}"
+  when: not ip_file_check.stat.exists
 
-- name: Check nfs exports file content
-  command: cat "{{ role_path }}/../control_plane_customiso/files/exports"
-  changed_when: false
-  register: check_exports_path
-  run_once: true
-  when:
-    - '"awx-" in hostname.stdout'
-    - nfs_exports_present.stat.exists
+- name: Set management_station_ip
+  set_fact:
+    management_station_ip: "{{ fetch_ip.stdout }}"
+
+- name: Check NFS share access
+  idrac_server_config_profile:
+    idrac_ip: "{{ inventory_hostname }}"
+    idrac_user: "{{ idrac_username }}"
+    idrac_password: "{{ idrac_password }}"
+    share_name: "{{ management_station_ip }}:{{ nfs_share_offline_repo }}"
+    command: "export"
+    scp_components: "BIOS"
+    scp_file: "{{ nfs_check_file }}"
+    export_format: XML
+    export_use: Default
+    job_wait: true
+  register: nfs_check
+  ignore_errors: true
 
 - name: Missing entries in nfs exports
   fail:
     msg: "{{ missing_exports_fail_msg }}"
   when:
-    - '"awx-" in hostname.stdout'
-    - not nfs_exports_present.stat.exists or
-      check_exports_path.rc == 1 or
-      inventory_hostname not in check_exports_path.stdout
-
-- name: Fetch management station ip from exports file
-  shell: awk 'FNR==1' {{ role_path }}/../control_plane_customiso/files/exports | awk '{print $2}'
-  changed_when: false
-  register: fetch_public_ip
-  when: '"awx-" in hostname.stdout'
-
-- name: Set public ip
-  set_fact:
-    public_ip: "{{ fetch_public_ip.stdout.split(\"(\")[0] }}"
-  when: '"awx-" in hostname.stdout'
+    - nfs_check_key in nfs_check.msg or
+      nfs_check_key in nfs_check.scp_status.Status
 
 - name: Initialize variables
   set_fact:
@@ -91,25 +75,102 @@
     datacenter_license: false
     provision_status: false
 
-- name: Check provisioned_idrac_ip.yml file present
-  stat:
-    path: "{{ role_path }}/files/provisioned_idrac_ip.yml"
-  register: provisioned_file_present
+- name: Check tower_cli.cfg is encrypted
+  command: cat "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+  changed_when: false
+  register: awx_content
+  run_once: true
+  when: awx_search_key in hostname.stdout
+
+- name: Decrpyt tower_cli.cfg
+  command: >-
+    ansible-vault decrypt "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+    --vault-password-file "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vaultname }}"
+  changed_when: false
+  run_once: true
+  when:
+    - awx_search_key in hostname.stdout
+    - "'$ANSIBLE_VAULT;' in awx_content.stdout"
+
+- name: Fetch awx host
+  command: grep "host:" "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+  register: fetch_awx_host
+  changed_when: false
   run_once: true
+  when: awx_search_key in hostname.stdout
 
-- name: Check idrac server is already provisioned
-  command: cat {{ role_path }}/files/provisioned_idrac_ip.yml
+- name: Fetch awx username
+  command: grep "username:" "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+  register: fetch_awx_username
   changed_when: false
-  register: check_provision_status
-  when: provisioned_file_present.stat.exists
   run_once: true
+  no_log: true
+  when: awx_search_key in hostname.stdout
+
+- name: Fetch awx password
+  command: grep "password:" "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+  register: fetch_awx_password
+  changed_when: false
+  run_once: true
+  no_log: true
+  when: awx_search_key in hostname.stdout
+
+- name: Set awx variables
+  set_fact:
+    awx_host: "{{ fetch_awx_host.stdout | regex_replace('host: ','') }}"
+    awx_username: "{{ fetch_awx_username.stdout | regex_replace('username: ','') }}"
+    awx_password: "{{ fetch_awx_password.stdout | regex_replace('password: ','') }}"
+  no_log: true
+  when: awx_search_key in hostname.stdout
+
+- name: Encrypt tower_cli.cfg
+  command: >-
+    ansible-vault encrypt "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vars_filename }}"
+    --vault-password-file "{{ playbook_dir }}/roles/webui_awx/files/{{ awx_vaultname }}"
+  changed_when: false
+  run_once: true
+  when:
+    - awx_search_key in hostname.stdout
+    - "'$ANSIBLE_VAULT;' in awx_content.stdout"
+
+- name: Get inventory list
+  command: >-
+     awx --conf.host "{{ awx_host }}" --conf.username "{{ awx_username }}" --conf.password "{{ awx_password }}"
+     inventory list -f human --filter "name"
+  register: inventory_list
+  run_once: true
+  changed_when: false
+  no_log: true
+  when: awx_search_key in hostname.stdout
+
+- name: Create provisioned_idrac inventory
+  command: >-
+    awx --conf.host {{ awx_host }} --conf.username {{ awx_username }} --conf.password {{ awx_password }}
+    inventory create --name "{{ provisioned_idrac_inventory_name }}" --organization "{{ awx_organization }}"
+  register: create_inventory
+  run_once: true
+  changed_when: true
+  no_log: true
+  when:
+    - awx_search_key in hostname.stdout
+    - provisioned_idrac_inventory_name not in inventory_list.stdout
+
+- name: Fetch provisioned_idrac inventory
+  command: >-
+    awx --conf.host {{ awx_host }} --conf.username {{ awx_username }} --conf.password {{ awx_password }}
+    hosts list --inventory "{{ provisioned_idrac_inventory_name }}" -f human --filter "name"
+  register: fetch_inventory
+  run_once: true
+  changed_when: false
+  no_log: true
+  when: awx_search_key in hostname.stdout
 
 - name: Removing hosts already provisioned
   fail:
-    msg: "{{ provision_fail_msg }}"
+    msg: "{{ provision_skip_msg }}"
   when:
-    - provisioned_file_present.stat.exists
-    - inventory_hostname in check_provision_status.stdout
+    - awx_search_key in hostname.stdout
+    - inventory_hostname in fetch_inventory.stdout
 
 - name: Show status of the Lifecycle Controller
   dellemc.openmanage.idrac_lifecycle_controller_status_info:

+ 11 - 3
control_plane/roles/provision_idrac/tasks/create_vd.yml

@@ -31,13 +31,18 @@
     idrac_password: "{{ idrac_password }}"
     state: "view"
   register: idrac_volume_list
-  when: raid_type and not raid_vd_status
+  when: 
+    - raid_type
+    - not raid_vd_status
 
 - name: Set drives details
   set_fact:
     drives_id: "{{ idrac_volume_list.storage_status.Message.Controller[raid_controller_sensor].Enclosure[raid_enclosure_name].PhysicalDisk }}"
     drives_count: "{{ idrac_volume_list.storage_status.Message.Controller[raid_controller_sensor].Enclosure[raid_enclosure_name].PhysicalDisk | length }}"
-  when: raid_type and not raid_vd_status
+  when: 
+    - raid_type
+    - not raid_vd_status
+    - idrac_volume_list.storage_status.Message.Controller[raid_controller_sensor].Enclosure[raid_enclosure_name].PhysicalDisk is defined
 
 - name: Create VD
   dellemc.openmanage.dellemc_idrac_storage_volume:
@@ -55,4 +60,7 @@
         drives:
           id: "{{ drives_id }}"
   register: create_vd_status
-  when: raid_type and not raid_vd_status
+  when: 
+    - raid_type
+    - not raid_vd_status
+    - idrac_volume_list.storage_status.Message.Controller[raid_controller_sensor].Enclosure[raid_enclosure_name].PhysicalDisk is defined

+ 16 - 7
control_plane/roles/provision_idrac/tasks/deploy_os.yml

@@ -37,16 +37,25 @@
     idrac_ip: "{{ inventory_hostname }}"
     idrac_user: "{{ idrac_username }}"
     idrac_password: "{{ idrac_password }}"
-    share_name: "{{ public_ip }}:{{ nfs_share_offline_repo }}"
+    share_name: "{{ management_station_ip }}:{{ nfs_share_offline_repo }}"
     iso_image: "{{ unattended_iso_filename }}"
     expose_duration: "{{ expose_duration }}"
   register: deploy_os
   when: enterprise_license or datacenter_license
 
-- name: Add idrac ip to provisioned_idrac_ip.yml
-  lineinfile:
-    path: "{{ role_path }}/files/provisioned_idrac_ip.yml"
-    create: yes
-    mode: "{{ file_permission }}"
-    line: "{{ inventory_hostname }}"
+- name: Add to provisioned_hosts to inventory
+  command: >-
+    awx --conf.host {{ awx_host }} --conf.username {{ awx_username }} --conf.password {{ awx_password }} 
+    hosts create --name {{ inventory_hostname }} --inventory "{{ provisioned_idrac_inventory_name }}"
+  register: update_inventory
+  changed_when: true
+  no_log: true
+  when:
+    - awx_search_key in hostname.stdout
+    - inventory_hostname not in fetch_inventory.stdout
+    - not deploy_os.failed
+
+- name: Provision OS status
+  debug:
+    msg: "{{ provision_os_msg }}"
   when: not deploy_os.failed

+ 15 - 34
control_plane/roles/provision_idrac/tasks/import_scp.yml

@@ -13,52 +13,33 @@
 # limitations under the License.
 ---
 
-- name: Remove the scp file if exists
+- name: Remove the SCP file if exists
   file:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     state: absent
   run_once: true
 
-- name: Create scp file
+- name: Create SCP file
   copy:
     src: "{{ role_path }}/files/temp_scp.xml"
     dest: "{{ role_path }}/files/{{ scp_filename }}"
     mode: preserve
   run_once: true
 
-- name: Add system profile value Performance to scp file
+- name: Add system profile value to SCP file
   lineinfile:
     path: "{{ role_path }}/files/{{ scp_filename }}"
-    line: '  <Attribute Name="SysProfile">PerfOptimized</Attribute>'
+    line: "{{ item.line }}"
     insertafter: '^(.*)BootSeqRetry'
-  when: idrac_system_profile == "Performance"
-  run_once: true
-
-- name: Add system profile value PerformancePerWatt(OS) to scp file
-  lineinfile:
-    path: "{{ role_path }}/files/{{ scp_filename }}"
-    line: '  <Attribute Name="SysProfile">PerfPerWattOptimizedOs</Attribute>'
-    insertafter: '^(.*)BootSeqRetry'
-  when: idrac_system_profile == "PerformancePerWatt(OS)"
-  run_once: true
-
-- name: Add system profile value PerformancePerWatt(DAPC) to scp file
-  lineinfile:
-    path: "{{ role_path }}/files/{{ scp_filename }}"
-    line: '  <Attribute Name="SysProfile">PerfPerWattOptimizedDapc</Attribute>'
-    insertafter: '^(.*)BootSeqRetry'
-  when: idrac_system_profile == "PerformancePerWatt(DAPC)"
-  run_once: true
-
-- name: Add system profile value WorkstationPerformance to scp file
-  lineinfile:
-    path: "{{ role_path }}/files/{{ scp_filename }}"
-    line: '  <Attribute Name="SysProfile">PerfWorkStationOptimized</Attribute>'
-    insertafter: '^(.*)BootSeqRetry'
-  when: idrac_system_profile == "WorkstationPerformance"
+  when: idrac_system_profile == item.name
+  with_items:
+    - { name: "Performance", line: "  <Attribute Name=\"SysProfile\">PerfOptimized</Attribute>" }
+    - { name: "PerformancePerWatt(OS)", line: "  <Attribute Name=\"SysProfile\">PerfPerWattOptimizedOs</Attribute>" }
+    - { name: "PerformancePerWatt(DAPC)", line: "  <Attribute Name=\"SysProfile\">PerfPerWattOptimizedDapc</Attribute>" }
+    - { name: "WorkstationPerformance", line: "  <Attribute Name=\"SysProfile\">PerfWorkStationOptimized</Attribute>" }
   run_once: true
 
-- name: Add PXE attributes to scp file
+- name: Add PXE attributes to SCP file
   lineinfile:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     line: "{{ item }}"
@@ -73,7 +54,7 @@
   when: not (enterprise_license or datacenter_license)
   run_once: true
 
-- name: Disable PXE attributes to scp file
+- name: Disable PXE attributes to SCP file
   lineinfile:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     line: '  <Attribute Name="PxeDev1EnDis">Disabled</Attribute>'
@@ -81,14 +62,14 @@
   when: enterprise_license or datacenter_license
   run_once: true
 
-- name: Add SNMP community name attribute to scp file
+- name: Add SNMP community name attribute to SCP file
   lineinfile:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     line: '  <Attribute Name="SNMP.1#AgentCommunity">{{ snmp_community_name }}</Attribute>'
     insertafter: '^(.*)SNMP.1#AgentEnable'
   run_once: true
 
-- name: Add SNMP trap destination attributes to scp file
+- name: Add SNMP trap destination attributes to SCP file
   lineinfile:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     line: "{{ item }}"
@@ -112,7 +93,7 @@
     job_wait: "True"
   register: import_scp_status
 
-- name: Remove the scp file
+- name: Remove the SCP file
   file:
     path: "{{ role_path }}/files/{{ scp_filename }}"
     state: absent

+ 4 - 0
control_plane/roles/provision_idrac/tasks/main.yml

@@ -21,6 +21,10 @@
 - name: Check prerequisites
   include_tasks: check_prerequisites.yml
 
+- name: Update firmware
+  include_tasks: update_firmware.yml
+  when: firmware_update_required
+
 - name: Import SCP
   include_tasks: import_scp.yml
 

+ 37 - 0
control_plane/roles/provision_idrac/tasks/update_firmware.yml

@@ -0,0 +1,37 @@
+# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+---
+
+- name: Update firmware (This task will take time based on current firmware version)
+  dellemc.openmanage.idrac_firmware:
+    idrac_ip: "{{ inventory_hostname }}"
+    idrac_user: "{{ idrac_username }}"
+    idrac_password: "{{ idrac_password }}"
+    share_name: "{{ management_station_ip }}:{{ nfs_share_offline_repo }}/dellupdates"
+    reboot: True
+    job_wait: True
+    apply_update: True
+    catalog_file_name: "Catalog.xml"
+  register: update_firmware
+
+- name: Wait for one minute to complete firmware update
+  wait_for:
+    timeout: 60 
+  run_once: true
+
+- name: Wait for iDRAC port to become active
+  wait_for:
+    host: "{{ inventory_hostname }}"
+    port: "{{ idrac_port }}"
+    state: started

+ 2 - 17
control_plane/roles/provision_idrac/tasks/validate_idrac_vars.yml

@@ -74,29 +74,14 @@
   register: hostname
   run_once: true
 
-- name: Fetch the system public IP
-  set_fact:
-    public_ip: "{{ lookup('vars','ansible_'+public_nic).ipv4.address }}"
-  run_once: true
-  when: '"awx-" not in hostname.stdout'
-
-- name: Assert public IP
-  assert:
-    that:
-      - public_ip | length > 7
-      - public_ip | ipv4
-    success_msg: "{{ public_ip_success_msg }}"
-    fail_msg: "{{ public_ip_fail_msg }}"
-  when: '"awx-" not in hostname.stdout'
-
 - name: Fetch idrac credentials
   include_tasks: fetch_idrac_credentials.yml
-  when: '"awx-" not in hostname.stdout'
+  when: awx_search_key not in hostname.stdout
 
 - name: Set idrac credentials
   set_fact:
     idrac_username: "{{ lookup('env','ANSIBLE_NET_USERNAME') }}"
     idrac_password: "{{ lookup('env','ANSIBLE_NET_PASSWORD') }}"
   no_log: true
-  when: '"awx-" in hostname.stdout'
+  when: awx_search_key in hostname.stdout
   run_once: true

+ 16 - 6
control_plane/roles/provision_idrac/vars/main.yml

@@ -33,17 +33,27 @@ public_ip_success_msg: "public_ip validated"
 public_ip_fail_msg: "Failed. Incorrect value for public_nic in base_vars.yml"
 
 # Usage: check_prerequisites.yml
-custom_iso_check_fail_msg: "Custom ISO file is not present in the device. Please run appliance.yml first to create custom iso file unattended_centos7.iso"
-missing_exports_fail_msg: "Missing iDRAC IP entry in /etc/exports file. Wait for 10 minutes and retry again"
-lc_check_fail_msg: "LC is not ready. Retry again after LC is ready"
-provision_fail_msg: "Skipping remaining tasks for already provisioned servers. To provision server again remove iDRAC IP from the file control_plane/roles/provision_idrac/files/provisioned_idrac_ip.yml"
+missing_exports_fail_msg: "Failed. Missing network cidr entry of iDRAC IP in /etc/exports file. Add entries if iDRAC IP is not in the management network range provided in base_vars.yml"
+lc_check_fail_msg: "Failed. LC is not ready. Retry again after LC is ready"
+provision_skip_msg: "Skipping remaining tasks for already provisioned servers. To provision server again remove iDRAC IP from the provision_idrac_inventory in awx"
+missing_ip_file_fail_msg: "Failed. Missing management_station_ip.txt in provision_idrac/files folder. Please run control_plane.yml to create management_station_ip.txt"
+awx_search_key: "awx-"
+nfs_check_key: "Failed"
+nfs_check_file: "nfs_check.xml"
+provisioned_idrac_inventory_name: "provisioned_idrac_inventory"
+awx_vars_filename: ".tower_cli.cfg"
+awx_vaultname: ".tower_vault_key"
+
+# Usage: update_firmware.yml
+idrac_port: 443
 
 # Usage: import_scp.yml
-scp_filename: idrac_scp.yml
+scp_filename: idrac_scp.xml
 
 # Usage: create_vd.yml
 raid_level: "RAID 0"
 
 # Usage: deploy_os.yml
 expose_duration: 60
-file_permission: 0644
+file_permission: 0644
+provision_os_msg: "OS provisioning is initiated. Wait for installation to complete for all servers."