---
###############################################################################
# Ironic inspector PXE configuration.

# List of extra kernel parameters for the inspector default PXE configuration.
inspector_extra_kernel_options: "{{ ipa_kernel_options }}"

# URL of Ironic Python Agent (IPA) kernel image.
inspector_ipa_kernel_upstream_url: "{{ ipa_kernel_upstream_url }}"

# URL of checksum of Ironic Python Agent (IPA) kernel image.
inspector_ipa_kernel_checksum_url: "{{ ipa_kernel_checksum_url }}"

# Algorithm of checksum of Ironic Python Agent (IPA) kernel image.
inspector_ipa_kernel_checksum_algorithm: "{{ ipa_kernel_checksum_algorithm }}"

# URL of Ironic Python Agent (IPA) ramdisk image.
inspector_ipa_ramdisk_upstream_url: "{{ ipa_ramdisk_upstream_url }}"

# URL of checksum of Ironic Python Agent (IPA) ramdisk image.
inspector_ipa_ramdisk_checksum_url: "{{ ipa_ramdisk_checksum_url }}"

# Algorithm of checksum of Ironic Python Agent (IPA) ramdisk image.
inspector_ipa_ramdisk_checksum_algorithm: "{{ ipa_ramdisk_checksum_algorithm }}"

###############################################################################
# Ironic inspector processing configuration.

# List of of default inspector processing plugins.
inspector_processing_hooks_default:
  - ramdisk_error
  - scheduler
  - validate_interfaces
  - capabilities
  - pci_devices
  - local_link_connection
  - lldp_basic

# List of of additional inspector processing plugins.
inspector_processing_hooks_extra: []

# List of of additional inspector processing plugins.
inspector_processing_hooks: >
  {{ inspector_processing_hooks_default + inspector_processing_hooks_extra }}

# Which MAC addresses to add as ports during introspection. One of 'all',
# 'active' or 'pxe'.
inspector_add_ports: "pxe"

# Which ports to keep after introspection. One of 'all', 'present', or 'added'.
inspector_keep_ports: "added"

# Whether to enable discovery of nodes not managed by Ironic.
inspector_enable_discovery: True

# The Ironic driver with which to register newly discovered nodes.
inspector_discovery_enroll_node_driver: "ipmi"

###############################################################################
# Ironic inspector configuration.

# Ironic inspector IPMI username to set.
inspector_ipmi_username: "{{ ipmi_username }}"

# Ironic inspector IPMI password to set.
inspector_ipmi_password: "{{ ipmi_password }}"

# Ironic inspector default network interface name on which to check for an LLDP
# switch port description to use as the node's name.
inspector_lldp_switch_port_interface_default: eth0

# Ironic inspector map from hostname to network interface name on which to
# check for an LLDP switch port description to use as the node's name.
inspector_lldp_switch_port_interface_map: {}

###############################################################################
# Ironic inspector introspection rules configuration.

# IPMI username referenced by inspector rule.
inspector_rule_var_ipmi_username:

# IPMI password referenced by inspector rule.
inspector_rule_var_ipmi_password:

# Ironic inspector rule to set IPMI credentials.
inspector_rule_ipmi_credentials:
  description: "Set IPMI driver_info if no credentials"
  conditions:
    - field: "node://driver_info.ipmi_username"
      op: "is-empty"
    - field: "node://driver_info.ipmi_password"
      op: "is-empty"
  actions:
    - action: "set-attribute"
      path: "driver_info/ipmi_username"
      value: "{{ inspector_rule_var_ipmi_username }}"
    - action: "set-attribute"
      path: "driver_info/ipmi_password"
      value: "{{ inspector_rule_var_ipmi_password }}"

# Deployment kernel referenced by inspector rule.
inspector_rule_var_deploy_kernel:

# Ironic inspector rule to set deployment kernel.
inspector_rule_deploy_kernel:
  description: "Set deploy kernel"
  conditions:
    - field: "node://driver_info.deploy_kernel"
      op: "is-empty"
  actions:
    - action: "set-attribute"
      path: "driver_info/deploy_kernel"
      value: "{{ inspector_rule_var_deploy_kernel }}"

# Deployment ramdisk referenced by inspector rule.
inspector_rule_var_deploy_ramdisk:

# Ironic inspector rule to set deployment ramdisk.
inspector_rule_deploy_ramdisk:
  description: "Set deploy ramdisk"
  conditions:
    - field: "node://driver_info.deploy_ramdisk"
      op: "is-empty"
  actions:
    - action: "set-attribute"
      path: "driver_info/deploy_ramdisk"
      value: "{{ inspector_rule_var_deploy_ramdisk }}"

# Ironic inspector rule to set local boot capability
inspector_rule_local_boot:
  description: "Set local boot capability"
  conditions: []
  actions:
    - action: "set-capability"
      name: "boot_option"
      value: "local"

# Ironic inspector rule to initialise root device hints.
inspector_rule_root_hint_init:
  description: "Initialise root device hint"
  conditions:
    - field: "node://properties.root_device"
      op: "is-empty"
  actions:
    # Inspector can't combine references to introspection data with non-string
    # types, see https://bugs.launchpad.net/ironic-inspector/+bug/1670768. We
    # must therefore first set the root_device property to an empty dict, then
    # update the fields within it.
    - action: "set-attribute"
      path: "properties/root_device"
      value: {}

# Ironic inspector rule to set serial root device hint.
inspector_rule_root_hint_serial:
  description: "Set serial root device hint"
  conditions:
    - field: "data://root_disk.serial"
      op: "is-empty"
      invert: True
  actions:
    - action: "set-attribute"
      path: "properties/root_device/serial"
      value: "{data[root_disk][serial]}"

# Ironic inspector rule to set the interface on which the node PXE booted.
inspector_rule_set_pxe_interface_mac:
  description: "Set node PXE interface MAC address"
  conditions:
    - field: "data://boot_interface"
      op: "is-empty"
      invert: True
  actions:
    - action: "set-attribute"
      path: "extra/pxe_interface_mac"
      value: "{data[boot_interface]}"

# Name of network interface to use for LLDP referenced by switch port
# description rule.
inspector_rule_var_lldp_switch_port_interface:

# Ironic inspector rule to set the node's name from an interface's LLDP switch
# port description.
inspector_rule_lldp_switch_port_desc_to_name:
  description: "Set node name from {{ inspector_rule_var_lldp_switch_port_interface }} LLDP switch port description"
  conditions:
    # Check for the existence of the switch_port_description field.
    - 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
    # Filter out switch port descriptions using the switch's interface names.
    # On some switches (including Dell Network OS 9.10(0.1)), the port
    # description TLV is sent but contains the interface name rather than the
    # interface's description.
    - field: "data://all_interfaces.{{inspector_rule_var_lldp_switch_port_interface}}.lldp_processed.switch_port_description"
      op: "matches"
      value: "^GigabitEthernet ([0-9/]*)$"
      invert: True
    - field: "data://all_interfaces.{{inspector_rule_var_lldp_switch_port_interface}}.lldp_processed.switch_port_description"
      op: "matches"
      value: "^TenGigabitEthernet ([0-9/]*)$"
      invert: True
    - field: "data://all_interfaces.{{inspector_rule_var_lldp_switch_port_interface}}.lldp_processed.switch_port_description"
      op: "matches"
      value: "^fortyGigE ([0-9/]*)$"
      invert: True
    - field: "data://all_interfaces.{{inspector_rule_var_lldp_switch_port_interface}}.lldp_processed.switch_port_description"
      op: "matches"
      value: "^Port-channel ([0-9/]*)$"
      invert: True
  actions:
    - action: "set-attribute"
      path: "name"
      value: "{data[all_interfaces][{{ inspector_rule_var_lldp_switch_port_interface }}][lldp_processed][switch_port_description]}"

# Ironic inspector rule to initialise system vendor data in the node's metadata.
inspector_rule_save_system_vendor_init:
  description: "Initialise system vendor data in Ironic node metadata"
  conditions:
    - field: "data://inventory.system_vendor"
      op: "is-empty"
      invert: True
    - field: "node://extra.system_vendor"
      op: "is-empty"
  actions:
    - action: "set-attribute"
      path: "extra/system_vendor"
      value: {}

# Ironic inspector rule to save system vendor manufacturer data in the node's
# metadata.
inspector_rule_save_system_vendor_manufacturer:
  description: "Save system vendor manufacturer data in Ironic node metadata"
  conditions:
    - field: "data://inventory.system_vendor"
      op: "is-empty"
      invert: True
    - field: "data://inventory.system_vendor.manufacturer"
      op: "is-empty"
      invert: True
  actions:
    - action: "set-attribute"
      path: "extra/system_vendor/manufacturer"
      value: "{data[inventory][system_vendor][manufacturer]}"

# Ironic inspector rule to save system vendor serial number in the node's
# metadata.
inspector_rule_save_system_vendor_serial_number:
  description: "Save system vendor serial number in Ironic node metadata"
  conditions:
    - field: "data://inventory.system_vendor"
      op: "is-empty"
      invert: True
    - field: "data://inventory.system_vendor.serial_number"
      op: "is-empty"
      invert: True
  actions:
    - action: "set-attribute"
      path: "extra/system_vendor/serial_number"
      value: "{data[inventory][system_vendor][serial_number]}"

# Ironic inspector rule to save system vendor product name in the node's
# metadata.
inspector_rule_save_system_vendor_product_name:
  description: "Save system vendor product name in Ironic node metadata"
  conditions:
    - field: "data://inventory.system_vendor"
      op: "is-empty"
      invert: True
    - field: "data://inventory.system_vendor.product_name"
      op: "is-empty"
      invert: True
  actions:
    - action: "set-attribute"
      path: "extra/system_vendor/product_name"
      value: "{data[inventory][system_vendor][product_name]}"

# Ironic inspector rule to save introspection data to the node.
inspector_rule_save_data:
  description: "Save introspection data to Ironic node"
  conditions: []
  actions:
    - action: "set-attribute"
      path: "extra/introspection_data"
      value: "{data}"

# List of default ironic inspector rules.
inspector_rules_default:
  - "{{ inspector_rule_ipmi_credentials }}"
  - "{{ inspector_rule_deploy_kernel }}"
  - "{{ inspector_rule_deploy_ramdisk }}"
  - "{{ inspector_rule_local_boot }}"
  - "{{ inspector_rule_root_hint_init }}"
  - "{{ inspector_rule_root_hint_serial }}"
  - "{{ inspector_rule_set_pxe_interface_mac }}"
  - "{{ inspector_rule_lldp_switch_port_desc_to_name }}"
  - "{{ inspector_rule_save_system_vendor_init }}"
  - "{{ inspector_rule_save_system_vendor_manufacturer }}"
  - "{{ inspector_rule_save_system_vendor_serial_number }}"
  - "{{ inspector_rule_save_system_vendor_product_name }}"

# List of additional ironic inspector rules.
inspector_rules_extra: []

# List of all ironic inspector rules.
inspector_rules: "{{ inspector_rules_default + inspector_rules_extra }}"

###############################################################################
# Dell switch LLDP workaround configuration.

# 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.

# Ansible group containing switch hosts to which the workaround should be
# applied.
inspector_dell_switch_lldp_workaround_group:

###############################################################################
# Inspection store configuration.
# The inspection store provides a Swift-like service for storing inspection
# data which may be useful in environments without Swift.

# Whether the inspection data store is enabled.
inspector_store_enabled: "{{ kolla_enable_ironic | bool and not kolla_enable_swift | bool }}"

# Port on which the inspection data store should listen.
inspector_store_port: 8080
