Register baremetal compute nodes in Ironic

This patch adds experimental functionallity to enroll baremetal nodes
into Ironic using Kayobe via a new playbook 'baremetal-compute-register.yml'
and adds 'kayobe baremetal compute register' into the Kayobe CLI.

Depends-On: I719fc8042742fe8b3b0312658aec39317a1bc358
Change-Id: I988b082b539acfc2710d42e89bcac5b7a1eb526a
This commit is contained in:
Jake Hutchinson 2024-02-21 14:19:00 +00:00
parent b9ca63dbea
commit 617eed4741
6 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,78 @@
---
- name: Register baremetal compute nodes
hosts: controllers[0]
vars:
venv: "{{ virtualenv_path }}/openstack-cli"
tasks:
- name: Set up openstack cli virtualenv
pip:
virtualenv: "{{ venv }}"
name:
- python-openstackclient
- python-ironicclient
state: latest
virtualenv_command: "python3.{{ ansible_facts.python.version.minor }} -m venv"
extra_args: "{% if pip_upper_constraints_file %}-c {{ pip_upper_constraints_file }}{% endif %}"
- name: Ensure baremetal compute nodes are registered in ironic
hosts: baremetal-compute
gather_facts: false
tags:
- baremetal
vars:
venv: "{{ virtualenv_path }}/openstack-cli"
controller_host: "{{ groups['controllers'][0] }}"
tasks:
- name: Check Ironic variables are defined
ansible.builtin.assert:
that:
- ironic_driver is defined
- ironic_driver_info is defined
- ironic_properties is defined
- ironic_resource_class is defined
fail_msg: One or more Ironic variables are undefined.
- block:
- name: Show baremetal node
ansible.builtin.command:
cmd: "{{ venv }}/bin/openstack baremetal node show {{ inventory_hostname }}"
register: node_show
failed_when:
- '"HTTP 404" not in node_show.stderr'
- node_show.rc != 0
changed_when: false
# NOTE: The openstack.cloud.baremetal_node module cannot be used in this
# script due to requiring a MAC address pre-defined, instead, this should
# be discovered by inpsection following this script.
#
# NOTE: IPMI address must be passed with Redfish address to ensure existing
# Ironic nodes match with new nodes during inspection.
- name: Create baremetal nodes
ansible.builtin.shell:
cmd: |
{{ venv }}/bin/openstack baremetal node create \
--name {{ inventory_hostname }} \
--driver {{ ironic_driver }} \
{% for key, value in ironic_driver_info.items() %}
--driver-info {{ key }}={{ value }} \
{% endfor %}
{% for key, value in ironic_properties.items() %}
--property {{ key }}={{ value }} \
{% endfor %}
--resource-class {{ ironic_resource_class }}
when:
- node_show.rc != 0
- name: Manage baremetal nodes
ansible.builtin.command:
cmd: "{{ venv }}/bin/openstack baremetal node manage {{ inventory_hostname }} --wait"
when:
- node_show.rc != 0
delegate_to: "{{ controller_host }}"
vars:
# NOTE: Without this, the controller's ansible_host variable will not
# be respected when using delegate_to.
ansible_host: "{{ hostvars[controller_host].ansible_host | default(controller_host) }}"
environment: "{{ openstack_auth_env }}"

View File

@ -13,6 +13,62 @@ By default these commands wait for the state transition to complete for each
node. This behavior can be changed by overriding the variable
``baremetal_compute_wait`` via ``-e baremetal_compute_wait=False``
Register
--------
This is an experimental workflow and acts as an alternative to enrolling nodes
through inspection where nodes can be registered in Ironic via kayobe given these
nodes are defined in the Kayobe inventory, an example hosts file for group r1 is below:
.. code-block:: ini
[r1]
hv100 ipmi_address=1.2.3.4
...
[baremetal-compute:children]
r1
You should also define a group_vars file for this group containing the Ironic
vars, this could be in ``etc/kayobe/inventory/group_vars/r1/ironic_vars`` or
in the environment you are using.
.. code-block:: yaml
ironic_driver: redfish
ironic_driver_info:
redfish_system_id: "{{ ironic_redfish_system_id }}"
redfish_address: "{{ ironic_redfish_address }}"
redfish_username: "{{ ironic_redfish_username }}"
redfish_password: "{{ ironic_redfish_password }}"
redfish_verify_ca: "{{ ironic_redfish_verify_ca }}"
ipmi_address: "{{ ipmi_address }}"
ironic_properties:
capabilities: "{{ ironic_capabilities }}"
ironic_resource_class: "example_resouce_class"
ironic_redfish_system_id: "/redfish/v1/Systems/System.Embedded.1"
ironic_redfish_verify_ca: "{{ inspector_rule_var_redfish_verify_ca }}"
ironic_redfish_address: "{{ ipmi_address }}"
ironic_redfish_username: "{{ inspector_redfish_username }}"
ironic_redfish_password: "{{ inspector_redfish_password }}"
ironic_capabilities: "boot_option:local,boot_mode:uefi"
It's essential that the Ironic username and password match the BMC username
and password for your nodes, if the username and password combination is
not the same for the entire group you will need to adjust your configuration
accordingly. The IPMI address should also match the BMC address for your node.
Once this has been completed you can begin enrolling the Ironic nodes::
(kayobe) $ kayobe baremetal compute register
Inspector is not used to discover nodes and no node inspection will take place on
enrollment, nodes will automatically be placed into ``manageable`` state. To inspect,
you should use ``kayobe baremetal compute inspect`` following enrollment.
Manage
------

View File

@ -1858,6 +1858,14 @@ class NetworkConnectivityCheck(KayobeAnsibleMixin, VaultMixin, Command):
playbooks = _build_playbook_list("network-connectivity")
self.run_kayobe_playbooks(parsed_args, playbooks)
class BaremetalComputeRegister(KayobeAnsibleMixin, VaultMixin, Command):
"""Register baremetal compute nodes in Ironic."""
def take_action(self, parsed_args):
self.app.LOG.debug("Register baremetal compute nodes in Ironic.")
playbooks = _build_playbook_list("baremetal-compute-register")
self.run_kayobe_playbooks(parsed_args, playbooks)
class BaremetalComputeInspect(KayobeAnsibleMixin, VaultMixin, Command):
"""Perform hardware inspection on baremetal compute nodes."""

View File

@ -2169,6 +2169,25 @@ class TestCase(unittest.TestCase):
]
self.assertListEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_baremetal_compute_register(self, mock_run):
command = commands.BaremetalComputeRegister(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
result = command.run(parsed_args)
self.assertEqual(0, result)
expected_calls = [
mock.call(
mock.ANY,
[
utils.get_data_files_path(
"ansible", "baremetal-compute-register.yml"),
],
),
]
self.assertListEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_baremetal_compute_inspect(self, mock_run):

View File

@ -0,0 +1,6 @@
---
features:
- |
This patch adds experimental functionallity to enroll baremetal nodes
into Ironic using Kayobe via a new playbook 'baremetal-compute-register.yml'
and adds 'kayobe baremetal compute register' into the Kayobe CLI.

View File

@ -39,6 +39,7 @@ console_scripts=
kayobe-vault-password-helper = kayobe.cmd.kayobe_vault_password_helper:main
kayobe.cli=
baremetal_compute_register = kayobe.cli.commands:BaremetalComputeRegister
baremetal_compute_inspect = kayobe.cli.commands:BaremetalComputeInspect
baremetal_compute_introspection_data_save = kayobe.cli.commands:BaremetalComputeIntrospectionDataSave
baremetal_compute_manage = kayobe.cli.commands:BaremetalComputeManage
@ -106,6 +107,8 @@ kayobe.cli=
infra_vm_host_package_update = kayobe.cli.commands:InfraVMHostPackageUpdate
infra_vm_service_deploy = kayobe.cli.commands:InfraVMServiceDeploy
kayobe.cli.baremetal_compute_register =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.baremetal_compute_inspect =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.baremetal_compute_introspection_data_save =