7f767b1b4e
We use the group_by module to create groups based on host variables. When the variable is a boolean, we should convert it to a bool using the bool filter, to ensure that the group name has a consistent format.
113 lines
5.2 KiB
YAML
113 lines
5.2 KiB
YAML
---
|
|
# Some Dell switch OSs (including Dell Network OS 9.10(0.1)) do not support
|
|
# sending interface port description TLVs correctly. Instead of sending the
|
|
# interface description, they send the interface name (e.g. TenGigabitEthernet
|
|
# 1/1/1). This breaks the discovery process which relies on Ironic node
|
|
# introspection data containing the node's name in the interface port
|
|
# description. We work around this here by creating an introspection rule for
|
|
# each ironic node that matches against the switch system and the relevant
|
|
# interface name, then sets the node's name appropriately.
|
|
|
|
- name: Check whether Ironic is enabled
|
|
hosts: controllers
|
|
tasks:
|
|
- name: Create controllers group with ironic enabled
|
|
group_by:
|
|
key: "controllers_with_ironic_enabled_{{ kolla_enable_ironic | bool }}"
|
|
|
|
- name: Group controller hosts in systems requiring the workaround
|
|
hosts: controllers_with_ironic_enabled_True
|
|
gather_facts: False
|
|
tasks:
|
|
- name: Group controller hosts in systems requiring the Dell switch LLDP workaround
|
|
group_by:
|
|
key: "controllers_require_workaround_{{ groups[inspector_dell_switch_lldp_workaround_group] | default([]) | length > 0 }}"
|
|
|
|
- name: Ensure introspection rules for Dell switch LLDP workarounds are registered in Ironic Inspector
|
|
# Only required to run on a single host.
|
|
hosts: controllers_require_workaround_True[0]
|
|
gather_facts: False
|
|
vars:
|
|
all_switch_interfaces: []
|
|
ironic_inspector_rules: []
|
|
# This rule template is used in a with_subelements loop.
|
|
inspector_interface_mapping_rule:
|
|
description: "Set {{ item.1.1.description }} node name from {{ inspector_rule_var_lldp_switch_port_interface }} LLDP switch port description"
|
|
conditions:
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}"
|
|
op: "is-empty"
|
|
invert: True
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}.lldp_processed"
|
|
op: "is-empty"
|
|
invert: True
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}.lldp_processed.switch_port_description"
|
|
op: "is-empty"
|
|
invert: True
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}.lldp_processed.switch_system_name"
|
|
op: "is-empty"
|
|
invert: True
|
|
# Match against the interface name.
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}.lldp_processed.switch_port_description"
|
|
op: "eq"
|
|
# Our interface names may be of a shortened form e.g. Te1/1/1, but
|
|
# the port description will contain the full interface name. Use a
|
|
# regex to expand to the full form.
|
|
value: "{{ item.1.0 | regex_replace('^Te([a-zA-z ]*)([0-9/]+)$', 'TenGigabitEthernet \\2') }}"
|
|
# Match against the switch system name.
|
|
- field: "data://all_interfaces.{{ inspector_rule_var_lldp_switch_port_interface }}.lldp_processed.switch_system_name"
|
|
op: "eq"
|
|
value: "{{ item.0.host }}"
|
|
actions:
|
|
- action: "set-attribute"
|
|
path: "name"
|
|
value: "{{ item.1.1.description }}"
|
|
inspector_rule_var_lldp_switch_port_interface: "{{ inspector_lldp_switch_port_interface_map.get(item.1.1.description, inspector_lldp_switch_port_interface_default) }}"
|
|
|
|
pre_tasks:
|
|
- name: Validate OpenStack password authentication parameters
|
|
fail:
|
|
msg: >
|
|
Required OpenStack authentication parameter {{ item }} is
|
|
{% if item in openstack_auth %}empty{% else %}not present{% endif %}
|
|
in openstack_auth. Have you sourced the environment file?
|
|
when:
|
|
- openstack_auth_type == 'password'
|
|
- item not in openstack_auth or not openstack_auth[item]
|
|
with_items: "{{ openstack_auth_password_required_params }}"
|
|
tags:
|
|
- config-validation
|
|
|
|
# We build up the rules using a 2-step process. First we build a list of
|
|
# relevant switch hosts and their interface configuration (in list form).
|
|
# This allows us to use with_subelements in the next task to iterate over
|
|
# the interfaces for each switch.
|
|
- name: Update a fact containing switch interface configuration
|
|
set_fact:
|
|
all_switch_interfaces: >
|
|
{{ all_switch_interfaces +
|
|
[{'host': item.key,
|
|
'interface_config': item.value.switch_interface_config.items()}] }}
|
|
with_dict: "{{ hostvars }}"
|
|
when: item.key in groups[inspector_dell_switch_lldp_workaround_group]
|
|
|
|
- name: Update a fact containing Ironic Inspector rules
|
|
set_fact:
|
|
ironic_inspector_rules: >
|
|
{{ ironic_inspector_rules +
|
|
[inspector_interface_mapping_rule] }}
|
|
with_subelements:
|
|
- "{{ all_switch_interfaces }}"
|
|
- interface_config
|
|
when:
|
|
- item.1.1.description is defined
|
|
# Ignore VLAN interfaces.
|
|
- "'vlan' not in item.1.0"
|
|
# Ignore trunk links.
|
|
- "'-trunk' not in item.1.1.description"
|
|
|
|
roles:
|
|
- role: ironic-inspector-rules
|
|
ironic_inspector_venv: "{{ virtualenv_path }}/shade"
|
|
ironic_inspector_auth_type: "{{ openstack_auth_type }}"
|
|
ironic_inspector_auth: "{{ openstack_auth }}"
|