Skip to content

Commit 5359de4

Browse files
committed
Adds tools for idracs
1 parent 9366718 commit 5359de4

9 files changed

+353
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
3+
- hosts: baremetal-compute,overcloud
4+
gather_facts: false
5+
tasks:
6+
- command: /opt/dell/srvadmin/bin/idracadm7 -r {{ ipmi_address }} -u root -p {{ secrets_ipmi_password }} jobqueue delete -i JID_CLEARALL_FORCE
7+
delegate_to: localhost
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
- hosts: overcloud,baremetal-compute
3+
gather_facts: false
4+
connection: local
5+
6+
collections:
7+
- dellemc.openmanage
8+
9+
vars:
10+
secrets_ipmi_username: "{{ ipmi_admin_user }}"
11+
secrets_ipmi_password: "{{ ipmi_admin_password }}"
12+
drac_export_path: "{{ playbook_dir }}/idrac_export/"
13+
ansible_python_interpreter: "{{ ansible_playbook_python }}"
14+
15+
tasks:
16+
- name: Cancel all drac jobs
17+
dellemc.openmanage.idrac_lifecycle_controller_jobs:
18+
idrac_ip: "{{ ipmi_address }}"
19+
idrac_user: "{{ secrets_ipmi_username }}"
20+
idrac_password: "{{ secrets_ipmi_password }}"
21+
validate_certs: false
22+
delegate_to: localhost
23+
when: ipmi_address is defined
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
- hosts: baremetal-compute,overcloud
3+
gather_facts: false
4+
connection: local
5+
serial: "{{ lookup('env', 'ANSIBLE_SERIAL') | default(1, true) }}"
6+
7+
collections:
8+
- dellemc.openmanage
9+
10+
vars:
11+
# Run with ``-e dell_drm_apply_update=true`` to apply the firmware updates.
12+
dell_drm_apply_update: False
13+
dell_drm_address: "https://{{ oob_oc_net_name | net_ip(inventory_hostname=groups['seed'][0]) }}"
14+
secrets_ipmi_username: "{{ ipmi_admin_user }}"
15+
secrets_ipmi_password: "{{ ipmi_admin_password }}"
16+
# Look at the README for more details, but you need a repo
17+
# created in drm, and exported via a webserver:
18+
# drm --create -r=idrac_repo_joint --inputplatformlist=R640,R6525
19+
dell_drm_repo: "{{ ukaea_dell_drm_repo }}"
20+
controller_host: "{{ groups['controllers'][0] }}"
21+
venv: "{{ virtualenv_path }}/openstack-cli"
22+
tasks:
23+
- name: Set maintenance mode
24+
command: |-
25+
docker exec bifrost_deploy bash -c '
26+
OS_CLOUD=bifrost openstack baremetal node maintenance set \
27+
--reason "Running drac-firmware-update.yml" \
28+
{{ inventory_hostname }}'
29+
become: true
30+
delegate_to: "{{ groups.seed.0 }}"
31+
vars:
32+
ansible_connection: ssh
33+
ansible_host: "{{ hostvars[groups.seed.0].ansible_host }}"
34+
when: '"overcloud" in group_names'
35+
36+
- name: Set maintenance
37+
command: "{{ venv }}/bin/openstack baremetal node maintenance set {{ inventory_hostname }} --reason updates"
38+
vars:
39+
ansible_connection: ssh
40+
ansible_host: "{{ hostvars[controller_host].ansible_host }}"
41+
ansible_python_interpreter: "/opt/kayobe/venvs/openstack-cli/bin/python3"
42+
environment: "{{ openstack_auth_env }}"
43+
delegate_to: "{{ controller_host }}"
44+
when: '"overcloud" not in group_names'
45+
46+
- name: Update firmware from repository on a HTTP
47+
idrac_firmware:
48+
idrac_ip: "{{ ipmi_address }}"
49+
idrac_user: "{{ secrets_ipmi_username }}"
50+
idrac_password: "{{ secrets_ipmi_password }}"
51+
reboot: True
52+
job_wait: True
53+
apply_update: "{{ dell_drm_apply_update | bool }}"
54+
share_name: "{{ dell_drm_address }}"
55+
catalog_file_name: "{{ dell_drm_repo }}"
56+
ignore_cert_warning: True
57+
validate_certs: false
58+
register: idrac_firmware_output
59+
delegate_to: localhost
60+
when: ipmi_address is defined
61+
- debug:
62+
msg: "{{ idrac_firmware_output }}"
63+
64+
- name: Unset maintenance mode
65+
command: |-
66+
docker exec bifrost_deploy bash -c '
67+
OS_CLOUD=bifrost openstack baremetal node maintenance unset \
68+
{{ inventory_hostname }}'
69+
become: true
70+
delegate_to: "{{ groups.seed.0 }}"
71+
vars:
72+
ansible_connection: ssh
73+
ansible_host: "{{ hostvars[groups.seed.0].ansible_host }}"
74+
when: "'overcloud' in group_names"
75+
76+
- name: Unset maintenance
77+
command: "{{ venv }}/bin/openstack baremetal node maintenance unset {{ inventory_hostname }}"
78+
vars:
79+
ansible_connection: ssh
80+
ansible_host: "{{ hostvars[controller_host].ansible_host }}"
81+
ansible_python_interpreter: "/opt/kayobe/venvs/openstack-cli/bin/python3"
82+
environment: "{{ openstack_auth_env }}"
83+
delegate_to: "{{ controller_host }}"
84+
when: "'overcloud' not in group_names"
85+

etc/kayobe/ansible/drac-ping.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
3+
- hosts: baremetal-compute
4+
gather_facts: false
5+
tasks:
6+
- command: ping -c 1 {{ ipmi_address }}
7+
delegate_to: localhost
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
- hosts:
3+
- overcloud
4+
- baremetal-compute
5+
# Seemed to break connectivity
6+
- !lustre
7+
gather_facts: false
8+
connection: local
9+
10+
collections:
11+
- dellemc.openmanage
12+
13+
vars:
14+
secrets_ipmi_username: "{{ ipmi_admin_user }}"
15+
secrets_ipmi_password: "{{ ipmi_admin_password }}"
16+
# Annoyingly updating eventfilters requires a reboot
17+
drac_shutdown_type: "Graceful" # NoReboot or Graceful or Forced
18+
drac_export_path: "{{ playbook_dir }}"
19+
ansible_python_interpreter: "{{ ansible_playbook_python }}"
20+
21+
tasks:
22+
- name: Template golden config
23+
template:
24+
src: server-profiles/golden_IDRAC.json.j2
25+
dest: "server-profiles/golden_IDRAC_{{ inventory_hostname }}.json"
26+
mode: 0600
27+
28+
- name: Import Server Configuration Profile (IDRAC)
29+
idrac_server_config_profile:
30+
command: "import"
31+
idrac_ip: "{{ ipmi_address }}"
32+
idrac_user: "{{ secrets_ipmi_username }}"
33+
idrac_password: "{{ secrets_ipmi_password }}"
34+
share_name: "{{ drac_export_path }}"
35+
scp_file: "server-profiles/golden_IDRAC_{{ inventory_hostname}}.json"
36+
job_wait: true
37+
end_host_power_state: "On"
38+
shutdown_type: "{{ drac_shutdown_type }}"
39+
scp_components: ["IDRAC", "EventFilters"]
40+
validate_certs: false
41+
timeout: 60
42+
register: idrac_bios_output
43+
delegate_to: localhost
44+
when: ipmi_address is defined
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
- hosts:
3+
- overcloud
4+
- baremetal-compute
5+
gather_facts: false
6+
connection: local
7+
8+
collections:
9+
- dellemc.openmanage
10+
11+
vars:
12+
secrets_ipmi_username: "{{ ipmi_admin_user }}"
13+
secrets_ipmi_password: "{{ ipmi_admin_password }}"
14+
15+
# If you re-apply RAID, this recreates the disk!
16+
apply_raid: False
17+
drac_shutdown_type: "Graceful" # NoReboot or Graceful or Forced
18+
drac_export_path: "{{ playbook_dir }}"
19+
drac_profile_query_ironic: true
20+
ansible_python_interpreter: "{{ ansible_playbook_python }}"
21+
22+
tasks:
23+
#FIXME(wszumski): Unserstand what this does
24+
# - name: Import Server Configuration Profile (NIC)
25+
# idrac_server_config_profile:
26+
# command: "import"
27+
# idrac_ip: "{{ ipmi_address }}"
28+
# idrac_user: "{{ secrets_ipmi_username }}"
29+
# idrac_password: "{{ secrets_ipmi_password }}"
30+
# share_name: "{{ drac_export_path }}"
31+
# scp_file: "golden_BIOS_no_embedded_pxe.json"
32+
# job_wait: True
33+
# end_host_power_state: "On"
34+
# shutdown_type: "{{ drac_shutdown_type }}"
35+
# scp_components: "NIC"
36+
# register: idrac_nic_output
37+
# delegate_to: localhost
38+
# when: ipmi_address is defined
39+
#
40+
41+
- block:
42+
- name: Gather ironic state
43+
openstack.cloud.baremetal_node_info:
44+
name: "{{ inventory_hostname }}"
45+
register: node
46+
vars:
47+
ansible_python_interpreter: "{{ ansible_playbook_python }}"
48+
ansible_connection: local
49+
- name: Fail if hardware fault flag set
50+
fail:
51+
msg: >-
52+
Node has been flagged as having a hardware fault. Please clear the extra/kayobe_hardware_fault
53+
flag with `openstack baremetal node unset --extra kayobe_hardware_fault_<type>` if the fault has
54+
been resolved.
55+
when: node.nodes.0.extra | map('regex_search', '^kayobe_hardware_fault') | select | list | default([]) | truthy
56+
when: drac_profile_query_ironic | bool
57+
58+
- name: Import Server Configuration Profile (BIOS)
59+
idrac_server_config_profile:
60+
command: "import"
61+
idrac_ip: "{{ ipmi_address }}"
62+
idrac_user: "{{ secrets_ipmi_username }}"
63+
idrac_password: "{{ secrets_ipmi_password }}"
64+
share_name: "{{ drac_export_path }}"
65+
scp_file: "server-profiles/golden_BIOS_{{ drac_profile }}.json"
66+
job_wait: True
67+
end_host_power_state: "On"
68+
shutdown_type: "{{ drac_shutdown_type }}"
69+
scp_components: "BIOS"
70+
validate_certs: false
71+
timeout: 60
72+
register: idrac_bios_output
73+
delegate_to: localhost
74+
when: ipmi_address is defined
75+
76+
- name: Import Server Configuration Profile (RAID)
77+
idrac_server_config_profile:
78+
command: "import"
79+
idrac_ip: "{{ ipmi_address }}"
80+
idrac_user: "{{ secrets_ipmi_username }}"
81+
idrac_password: "{{ secrets_ipmi_password }}"
82+
share_name: "{{ drac_export_path }}"
83+
scp_file: "server-profiles/golden_RAID_{{ drac_profile }}.json"
84+
job_wait: True
85+
end_host_power_state: "On"
86+
shutdown_type: "{{ drac_shutdown_type }}"
87+
validate_certs: false
88+
register: idrac_bios_output
89+
register: idrac_raid_output
90+
delegate_to: localhost
91+
when: ipmi_address is defined and apply_raid
92+
93+
- name: Reset iDRAC if bios settings were updated
94+
idrac_reset:
95+
idrac_ip: "{{ ipmi_address }}"
96+
idrac_user: "{{ secrets_ipmi_username }}"
97+
idrac_password: "{{ secrets_ipmi_password }}"
98+
validate_certs: false
99+
register: idrac_bios_output
100+
when: ipmi_address is defined and idrac_bios_output.changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
- hosts: overcloud,baremetal-compute
3+
gather_facts: false
4+
connection: local
5+
6+
collections:
7+
- dellemc.openmanage
8+
9+
vars:
10+
secrets_ipmi_username: "{{ ipmi_admin_user }}"
11+
secrets_ipmi_password: "{{ ipmi_admin_password }}"
12+
drac_export_path: "{{ playbook_dir }}/idrac_export/"
13+
ansible_python_interpreter: "{{ ansible_playbook_python }}"
14+
15+
tasks:
16+
- name: Get System Inventory
17+
idrac_system_info:
18+
idrac_ip: "{{ ipmi_address }}"
19+
idrac_user: "{{ secrets_ipmi_username }}"
20+
idrac_password: "{{ secrets_ipmi_password }}"
21+
validate_certs: false
22+
delegate_to: localhost
23+
register: idrac_system_info
24+
when: ipmi_address is defined
25+
26+
- set_fact:
27+
model_name: "{{ idrac_system_info['system_info']['System'][0]['Model'] | replace('PowerEdge ','') }}"
28+
- name: get model
29+
debug:
30+
msg: "{{ model_name }}"
31+
32+
- name: Get Installed Firmware Inventory
33+
dellemc.openmanage.idrac_firmware_info:
34+
idrac_ip: "{{ ipmi_address }}"
35+
idrac_user: "{{ secrets_ipmi_username }}"
36+
idrac_password: "{{ secrets_ipmi_password }}"
37+
validate_certs: false
38+
delegate_to: localhost
39+
register: idrac_firmware_output
40+
when: ipmi_address is defined
41+
42+
- name: List installed components with firmware listed
43+
debug:
44+
msg: "{{ inventory_hostname }} hardware: {{ idrac_firmware_output['firmware_info']['Firmware'] | map(attribute='FQDD') | list | sort }}"
45+
46+
- name: Extract key firmware versions
47+
debug:
48+
msg: "{{ inventory_hostname }}:{{ item }}: {{ idrac_firmware_output['firmware_info']['Firmware'] | selectattr('FQDD', 'equalto', item) | map(attribute='VersionString') | list }}"
49+
loop:
50+
- "BIOS.Setup.1-1"
51+
- "iDRAC.Embedded.1-1"
52+
- "NIC.Slot.2-1-1" # Mellaonx NIC
53+
54+
- name: Ensure output dir exists
55+
file:
56+
state: directory
57+
path: "{{ drac_export_path }}"
58+
delegate_to: localhost
59+
run_once: True
60+
61+
- name: Export Server Configuration Profile
62+
idrac_server_config_profile:
63+
command: "export"
64+
export_format: "JSON"
65+
export_use: "Clone"
66+
idrac_ip: "{{ ipmi_address }}"
67+
idrac_user: "{{ secrets_ipmi_username }}"
68+
idrac_password: "{{ secrets_ipmi_password }}"
69+
share_name: "{{ drac_export_path }}"
70+
scp_file: "{{ inventory_hostname }}_{{ item }}.json"
71+
job_wait: "True"
72+
scp_components: "{{ item }}"
73+
validate_certs: false
74+
register: idrac_profile_output
75+
delegate_to: localhost
76+
when: ipmi_address is defined
77+
loop:
78+
- "BIOS"
79+
- "NIC"
80+
- "RAID"
81+
- "ALL"

etc/kayobe/ansible/requirements.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ collections:
1212
version: 2.7.1
1313
- name: stackhpc.kayobe_workflows
1414
version: 1.2.0
15+
- name: dellemc.openmanage
16+
version: 9.10.0
1517
roles:
1618
- src: stackhpc.vxlan
1719
version: 1.1.0

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
kayobe@git+https://github.com/stackhpc/kayobe@stackhpc/18.1.0.6
22
ansible-modules-hashivault>=5.3.0
33
jmespath
4+
omsdk==1.2.503
5+
# FIXME: I have no recollection of why I pinned these
6+
pysnmp==4.4.12
7+
urllib3<2

0 commit comments

Comments
 (0)