--- # This is a tasks file used by the idrac-bootstrap.yml playbook to support # bootstrapping the network configuration of a single iDRAC. # We use the following procedure to configure the iDRAC: # 1. Check whether the required IP is already reachable. Skip remaining tasks # if so. # 2. Configure the switch interface to which the iDRAC is attached as an # access port on the bootstrap VLAN. # 3. Clear the ARP cache on the controller in the bootstrap network namespace. # 4. Check whether the iDRAC default IP address is reachable. # 5. Enable IPMI on the iDRAC. # 6. Configure networking for the iDRAC. # 7. Configure the switch interface to which the iDRAC is attached as an # access port on the iDRAC management VLAN. - name: Check whether we can ping the iDRAC's configured IP address command: "ping -c 1 {{ idrac_network_ip }}" run_once: True # We use this convoluted method to allow a delegate_to with a variable host. # See http://www.elmund.io/configuration%20management/2015/07/23/ansible-delegate_to-and-variables/. with_items: - "{{ idrac_bootstrap_controller }}" loop_control: loop_var: delegate_host delegate_to: "{{ delegate_host }}" register: ping_result changed_when: False failed_when: False - name: Set a fact about whether the iDRAC requires bootstrapping set_fact: idrac_bootstrap_required: "{{ ping_result.results[0].rc != 0 }}" run_once: True - name: Display the result of the ping debug: msg: > The iDRAC on switch port with description {{ idrac_port_description }} and configured IP address {{ idrac_network_ip }} was {{ 'un' if idrac_bootstrap_required else '' }}reachable. The iDRAC will {{ '' if idrac_bootstrap_required else 'not ' }}be bootstrapped. run_once: True # The tasks in this block are only executed when the bootstrap is required. - block: - name: Ensure DellOS6 switch interface is a member of the bootstrap VLAN dellos6_config: provider: "{{ dell_switch_provider }}" lines: - "switchport access vlan {{ idrac_bootstrap_vlan }}" parents: - "interface {{ switch_interface_name }}" delegate_to: localhost when: switch_type == 'dellos6' # The tasks in this block are delegated to the controller. - block: - name: Ensure the iDRAC default IP address is removed from the controller's ARP cache command: > ip netns exec {{ idrac_bootstrap_net_namespace }} arp -d {{ idrac_default_ip }} become: True with_items: - "{{ idrac_bootstrap_controller }}" loop_control: loop_var: delegate_host delegate_to: "{{ delegate_host }}" register: arp_result failed_when: - arp_result | failed - "'No ARP entry for ' ~ idrac_default_ip not in arp_result.stdout" # Ansible's until keyword seems to not work nicely with failed_when, causing # the task to fail even though we have specified failed_when: False. - name: Check whether we can ping the iDRAC's default IP address shell: | max_attempts=3 interval=5 for attempt in $(seq $max_attempts); do ip netns exec {{ idrac_bootstrap_net_namespace }} \ ping -c 1 {{ idrac_default_ip }} ping_rc=$? if [[ $ping_rc -eq 0 ]] || [[ $attempt -eq $max_attempts ]]; then break fi sleep $interval done exit $ping_rc become: True with_items: - "{{ idrac_bootstrap_controller }}" loop_control: loop_var: delegate_host delegate_to: "{{ delegate_host }}" register: ping_result changed_when: False failed_when: False - name: Initialise a fact about whether iDRAC bootstrap failed set_fact: idrac_bootstrap_failure: {} - name: Set a fact about whether the iDRAC default IP was reachable set_fact: idrac_bootstrap_failure: "{{ ping_result.results[0] }}" when: ping_result.results[0].rc != 0 - name: Ensure IPMI is enabled on the iDRAC command: > ip netns exec {{ idrac_bootstrap_net_namespace }} /opt/dell/srvadmin/bin/idracadm7 -r {{ idrac_default_ip }} -u {{ idrac_default_username }} -p {{ idrac_default_password }} set iDRAC.IPMILan.Enable 1 become: True with_items: - "{{ idrac_bootstrap_controller }}" loop_control: loop_var: delegate_host delegate_to: "{{ delegate_host }}" when: not idrac_bootstrap_failure register: racadm_ipmi_enable failed_when: False - name: Set a fact about whether enabling IPMI on the iDRAC failed set_fact: idrac_bootstrap_failure: "{{ racadm_ipmi_enable.results[0] }}" when: - not idrac_bootstrap_failure - racadm_ipmi_enable.results[0].rc != 0 - name: Ensure the iDRAC IP address is configured command: > ip netns exec {{ idrac_bootstrap_net_namespace }} /opt/dell/srvadmin/bin/idracadm7 -r {{ idrac_default_ip }} -u {{ idrac_default_username }} -p {{ idrac_default_password }} setniccfg -s {{ idrac_network_ip }} {{ idrac_network_netmask }} {{ idrac_network_gateway }} become: True with_items: - "{{ idrac_bootstrap_controller }}" loop_control: loop_var: delegate_host delegate_to: "{{ delegate_host }}" when: not idrac_bootstrap_failure register: racadm_setniccfg failed_when: False - name: Set a fact about whether setting network configuration on the iDRAC failed set_fact: idrac_bootstrap_failure: "{{ racadm_setniccfg.results[0] }}" when: - not idrac_bootstrap_failure - racadm_setniccfg.results[0].rc != 0 - name: Append the iDRAC to the successful list on success set_fact: idrac_bootstrap_success: > {{ idrac_bootstrap_success + [idrac_port_description] }} when: not idrac_bootstrap_failure - name: Append the iDRAC to the failed list on failure set_fact: idrac_bootstrap_failed: > {{ idrac_bootstrap_failed + [{"port description": idrac_port_description, "failure": idrac_bootstrap_failure}] }} when: idrac_bootstrap_failure run_once: True # Ensure we reconfigure the switch interface. always: - name: Ensure DellOS6 switch iDRAC interface is a member of the management VLAN dellos6_config: provider: "{{ dell_switch_provider }}" lines: - "switchport access vlan {{ idrac_network_vlan }}" parents: - "interface {{ switch_interface_name }}" delegate_to: localhost when: switch_type == 'dellos6' when: idrac_bootstrap_required - name: Append the iDRAC to the unchanged list when unchanged set_fact: idrac_bootstrap_unchanged: > {{ idrac_bootstrap_unchanged + [idrac_port_description] }} run_once: True when: not idrac_bootstrap_required