129 lines
5.0 KiB
YAML
129 lines
5.0 KiB
YAML
---
|
|
- name: Check node has a resource class
|
|
fail:
|
|
msg: >
|
|
The `ironic_config` of node '{{ node }}' does not contain a
|
|
`resource_class`.
|
|
when: "'resource_class' not in node.ironic_config"
|
|
|
|
- name: Collect domain NIC MAC addresses
|
|
block:
|
|
- name: Get vNIC MAC addresses
|
|
# The output format of this command gives two lines of header, followed by
|
|
# (for each vNIC):
|
|
# <name> <type> <source interface> <model> <MAC>
|
|
command: >-
|
|
/usr/bin/virsh
|
|
{% if uri %}-c {{ uri }}{% endif %}
|
|
domiflist '{{ node.name }}'
|
|
vars:
|
|
uri: "{{ hostvars[ironic_hypervisor].libvirt_local_uri }}"
|
|
register: iflist_res
|
|
changed_when: false
|
|
become: true
|
|
delegate_to: "{{ ironic_hypervisor }}"
|
|
run_once: true
|
|
|
|
# We need to do this for each run to ensure other nodes' NICs don't carry over
|
|
# to this run.
|
|
- name: Reset list of NICs
|
|
set_fact:
|
|
nics: []
|
|
|
|
- name: Collect MAC addresses into NIC list
|
|
set_fact:
|
|
nics: "{{ nics | union([{'mac': item.split()[4]}]) }}"
|
|
loop: "{{ iflist_res.stdout_lines[2:] }}"
|
|
when: (node.state | default('present')) == 'present'
|
|
|
|
# If the node's state is 'absent', the domain will already have been
|
|
# destroyed.
|
|
when: (node.state | default('present')) == 'present'
|
|
|
|
- name: Configure node in Ironic
|
|
os_ironic:
|
|
auth_type: "{{ 'password' if lookup('env', 'OS_USERNAME') else omit }}"
|
|
cloud: "{{ lookup('env', 'OS_CLOUD') | default(omit, true) }}"
|
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
|
driver: "{{ node.ironic_driver }}"
|
|
driver_info:
|
|
power:
|
|
ipmi_address: "{{ hostvars[ironic_hypervisor].ipmi_address }}"
|
|
# This is passed in from main.yml.
|
|
ipmi_port: "{{ ipmi_port }}"
|
|
ipmi_username: "{{ hostvars[ironic_hypervisor].ipmi_username }}"
|
|
ipmi_password: "{{ hostvars[ironic_hypervisor].ipmi_password }}"
|
|
deploy:
|
|
deploy_kernel: "{{ ironic_deploy_kernel_uuid | default(omit, true) }}"
|
|
deploy_ramdisk: "{{ ironic_deploy_ramdisk_uuid | default(omit, true) }}"
|
|
name: "{{ node.name }}"
|
|
# The 'nics' list can be empty without a problem if state is 'absent'.
|
|
nics: "{{ nics | default([]) }}"
|
|
state: "{{ node.state | default('present') }}"
|
|
vars:
|
|
# This module requires the openstacksdk package, which is installed within
|
|
# our virtualenv.
|
|
ansible_python_interpreter: >-
|
|
{{ '/'.join([ironic_virtualenv_path, 'bin', 'python']) }}
|
|
register: node_res
|
|
|
|
- name: Perform node and port attribute manipulation
|
|
block:
|
|
# The os_ironic module automatically brings the node from 'enrol' to
|
|
# 'available' state, but we still need to set more port and node attributes.
|
|
# Use maintenance mode to do this.
|
|
- name: Put Ironic node into maintenance mode
|
|
command: >-
|
|
'{{ ironic_virtualenv_path }}/bin/openstack' baremetal node maintenance set
|
|
'{{ node_res.uuid }}'
|
|
|
|
- name: Set additional Ironic node attributes
|
|
command: >-
|
|
'{{ ironic_virtualenv_path }}/bin/openstack' baremetal node set
|
|
'{{ node_res.uuid }}'
|
|
--resource-class {{ node.ironic_config.resource_class }}
|
|
{% for iface in ironic_interfaces %}
|
|
{% if (iface + '_interface') in node.ironic_config %}
|
|
--{{ iface }}-interface {{ node.ironic_config[iface + '_interface'] }}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% for key, val in properties.iteritems() %}
|
|
--property '{{ key }}={{ val }}'
|
|
{% endfor %}
|
|
vars:
|
|
properties: "{{ default_properties | combine(custom_properties) }}"
|
|
custom_properties: "{{ node.ironic_config.get('properties', {}) }}"
|
|
# Although properties are not required for scheduling, the os_ironic module
|
|
# adds silly defaults that cause the validation API call to fail,
|
|
# preventing deployment. We add them here because the os_ironic module
|
|
# uses unusual names (cpus, ram, disk_size) for scheduling properties,
|
|
# and doesn't support setting other properties.
|
|
default_properties:
|
|
cpus: "{{ node.vcpus }}"
|
|
memory_mb: "{{ node.memory_mb }}"
|
|
local_gb: "{{ node.volumes[0].capacity | size_string_to_gb if node.volumes | length > 0 else 0 }}"
|
|
|
|
- name: Add Ironic node traits
|
|
command: >-
|
|
'{{ ironic_virtualenv_path }}/bin/openstack' baremetal node add trait
|
|
'{{ node_res.uuid }}'
|
|
{{ " ".join(node.ironic_config.traits) }}
|
|
when: node.ironic_config.traits | default([])
|
|
|
|
- name: Set additional Ironic port attributes
|
|
include_tasks: port.yml
|
|
vars:
|
|
source_interface: "{{ vnic.split()[2] }}"
|
|
mac: "{{ vnic.split()[4] }}"
|
|
# Loop over each NIC.
|
|
loop: "{{ iflist_res.stdout_lines[2:] }}"
|
|
loop_control:
|
|
loop_var: vnic
|
|
|
|
- name: Bring Ironic node out of maintenance mode
|
|
command: >-
|
|
'{{ ironic_virtualenv_path }}/bin/openstack' baremetal node maintenance
|
|
unset '{{ node_res.uuid }}'
|
|
|
|
when: (node.state | default('present')) == 'present'
|