From ea5d6a0301c6226866dd65c8a849308799d6b670 Mon Sep 17 00:00:00 2001 From: haseeb <184114777+haseebsyed12@users.noreply.github.com> Date: Mon, 19 May 2025 19:32:34 +0530 Subject: [PATCH 1/2] creating infra objects --- .typos.toml | 3 +- ansible/playbooks/openstack_baremetal.yaml | 29 +++++++++++++++++++ ansible/requirements.txt | 1 + .../roles/openstack_baremetal/tasks/main.yml | 9 ++++++ .../roles/openstack_baremetal/tasks/node.yml | 26 +++++++++++++++++ .../roles/openstack_baremetal/tasks/port.yml | 7 +++++ .../openstack_baremetal/tasks/port_group.yml | 17 +++++++++++ .../roles/openstack_network/tasks/main.yml | 25 ++++++++++++++++ .../roles/openstack_network/tasks/port.yml | 9 ++++++ .../openstack_network/tasks/segment_range.yml | 22 ++++++++++++++ .../openstack_network/tasks/subnet_pool.yml | 8 +++++ 11 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 ansible/playbooks/openstack_baremetal.yaml create mode 100644 ansible/roles/openstack_baremetal/tasks/main.yml create mode 100644 ansible/roles/openstack_baremetal/tasks/node.yml create mode 100644 ansible/roles/openstack_baremetal/tasks/port.yml create mode 100644 ansible/roles/openstack_baremetal/tasks/port_group.yml create mode 100644 ansible/roles/openstack_network/tasks/port.yml create mode 100644 ansible/roles/openstack_network/tasks/segment_range.yml create mode 100644 ansible/roles/openstack_network/tasks/subnet_pool.yml diff --git a/.typos.toml b/.typos.toml index ee031846e..40e4c2105 100644 --- a/.typos.toml +++ b/.typos.toml @@ -7,7 +7,6 @@ extend-exclude = [ "python/understack-workflows/tests/json_samples/", "containers/*/patches", "go.mod", - "ansible/roles/statuses/defaults/main.yaml", ] [default] @@ -20,4 +19,4 @@ extend-ignore-identifiers-re = [ HPE = "HPE" fo = "fo" sme = "sme" -4caf50 = "4caf50" +caf = "caf" diff --git a/ansible/playbooks/openstack_baremetal.yaml b/ansible/playbooks/openstack_baremetal.yaml new file mode 100644 index 000000000..5f4d6804b --- /dev/null +++ b/ansible/playbooks/openstack_baremetal.yaml @@ -0,0 +1,29 @@ +--- +# Copyright (c) 2025 Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Openstack Network + hosts: ironic + connection: local + + pre_tasks: + - name: Fail if ENV variables are not set + ansible.builtin.fail: + msg: "Environment variable {{ item }} is not set. Exiting playbook." + when: lookup('env', item) == '' + loop: + - OS_CLOUD + + roles: + - role: openstack_baremetal diff --git a/ansible/requirements.txt b/ansible/requirements.txt index 12954e6d4..a43c81896 100644 --- a/ansible/requirements.txt +++ b/ansible/requirements.txt @@ -5,3 +5,4 @@ pynautobot==2.6.2 jmespath==1.0.1 # remove me after the inherited roles workaround can be dropped python-openstackclient +python-ironicclient==5.11.0 diff --git a/ansible/roles/openstack_baremetal/tasks/main.yml b/ansible/roles/openstack_baremetal/tasks/main.yml new file mode 100644 index 000000000..289085375 --- /dev/null +++ b/ansible/roles/openstack_baremetal/tasks/main.yml @@ -0,0 +1,9 @@ +--- + +- name: Enroll infra nodes + ansible.builtin.include_tasks: node.yml + loop: "{{ infra_nodes }}" + loop_control: + loop_var: node + vars: + item: "{{ node }}" diff --git a/ansible/roles/openstack_baremetal/tasks/node.yml b/ansible/roles/openstack_baremetal/tasks/node.yml new file mode 100644 index 000000000..bdcf98049 --- /dev/null +++ b/ansible/roles/openstack_baremetal/tasks/node.yml @@ -0,0 +1,26 @@ +--- + +- name: Enroll infra node {{ item.name }} + openstack.cloud.baremetal_node: + name: "{{ item.name }}" + driver: "{{ item.driver }}" + driver_info: "{{ item.driver_info }}" + nics: "{{ item.nics }}" + state: present + register: enrolled_node + +- name: Create baremetal ports for node {{ item.name }} + ansible.builtin.include_tasks: port.yml + loop: "{{ item.nics }}" + loop_control: + loop_var: port_info + vars: + port_node_name: "{{ item.name }}" + +- name: Create baremetal ports group for node {{ item.name }} + ansible.builtin.include_tasks: port_group.yml + loop: "{{ item.port_groups }}" + loop_control: + loop_var: port_group + vars: + node_id: "{{ enrolled_node.node.id }}" diff --git a/ansible/roles/openstack_baremetal/tasks/port.yml b/ansible/roles/openstack_baremetal/tasks/port.yml new file mode 100644 index 000000000..d93ba01d0 --- /dev/null +++ b/ansible/roles/openstack_baremetal/tasks/port.yml @@ -0,0 +1,7 @@ +--- + +- name: Create baremetal port + openstack.cloud.baremetal_port: + address: "{{ port_info.mac }}" + node: "{{ port_node_name }}" + state: present diff --git a/ansible/roles/openstack_baremetal/tasks/port_group.yml b/ansible/roles/openstack_baremetal/tasks/port_group.yml new file mode 100644 index 000000000..525e92110 --- /dev/null +++ b/ansible/roles/openstack_baremetal/tasks/port_group.yml @@ -0,0 +1,17 @@ +--- + +- name: Check if baremetal port group exists + ansible.builtin.command: openstack baremetal port group show {{ port_group.name }} + register: port_group_check + failed_when: false + changed_when: false + +- name: Create baremetal port group + ansible.builtin.shell: > + openstack baremetal port group create + --node {{ node_id }} + --name {{ port_group.name }} + --mode {{ port_group.mode }} + when: port_group_check.rc != 0 + register: port_group_created + changed_when: true diff --git a/ansible/roles/openstack_network/tasks/main.yml b/ansible/roles/openstack_network/tasks/main.yml index cbf4b01ea..04b081c8c 100644 --- a/ansible/roles/openstack_network/tasks/main.yml +++ b/ansible/roles/openstack_network/tasks/main.yml @@ -17,3 +17,28 @@ loop: "{{ existing_networks.results }}" loop_control: label: "{{ item.item.network_name }}" + +- name: Create segment range + ansible.builtin.include_tasks: segment_range.yml + loop: "{{ network_segment_ranges }}" + loop_control: + loop_var: segment + vars: + item: "{{ segment }}" + +- name: Create subnet pool + ansible.builtin.include_tasks: subnet_pool.yml + loop: "{{ subnet_pools }}" + loop_control: + loop_var: subnet_pool + vars: + item: "{{ subnet_pool }}" + +- name: Create baremetal ports + ansible.builtin.include_tasks: port.yml + loop: "{{ baremetal_ports }}" + loop_control: + loop_var: network_ports + vars: + ports: "{{ network_ports.ports }}" + network: "{{ network_ports.network }}" diff --git a/ansible/roles/openstack_network/tasks/port.yml b/ansible/roles/openstack_network/tasks/port.yml new file mode 100644 index 000000000..9655794c7 --- /dev/null +++ b/ansible/roles/openstack_network/tasks/port.yml @@ -0,0 +1,9 @@ +--- + +- name: Create neutron port for network {{ network }} + openstack.cloud.port: + state: present + name: "{{ item.name }}" + mac_address: "{{ item.mac_address }}" + network: "{{ network }}" + loop: "{{ ports }}" diff --git a/ansible/roles/openstack_network/tasks/segment_range.yml b/ansible/roles/openstack_network/tasks/segment_range.yml new file mode 100644 index 000000000..1ba84c166 --- /dev/null +++ b/ansible/roles/openstack_network/tasks/segment_range.yml @@ -0,0 +1,22 @@ +--- + +- name: Check if segment range exists + ansible.builtin.command: openstack network segment range show {{ item.name }} + register: segment_range_check + failed_when: false + changed_when: false + +- name: Create network segment range if missing + ansible.builtin.shell: > + openstack network segment range create + --shared + --network-type {{ item['network-type'] }} + --minimum {{ item.range_min }} + --maximum {{ item.range_max }} + {% if item.get('physical-network', '') | length > 0 %} + --physical-network {{ item['physical-network'] }} + {% endif %} + {{ item.name }} + when: segment_range_check.rc != 0 + register: segment_range_created + changed_when: true diff --git a/ansible/roles/openstack_network/tasks/subnet_pool.yml b/ansible/roles/openstack_network/tasks/subnet_pool.yml new file mode 100644 index 000000000..1f2de1e34 --- /dev/null +++ b/ansible/roles/openstack_network/tasks/subnet_pool.yml @@ -0,0 +1,8 @@ +--- + +- name: Create subnet pool for OUTSIDE network + openstack.cloud.subnet_pool: + state: present + name: "{{ item.name }}" + is_shared: true + prefixes: "{{ item.prefixes }}" From 4f370123387daa6577cffbfc3484d832fba72e5c Mon Sep 17 00:00:00 2001 From: haseeb <184114777+haseebsyed12@users.noreply.github.com> Date: Thu, 22 May 2025 23:06:18 +0530 Subject: [PATCH 2/2] review comments --- ansible/playbooks/openstack_baremetal.yaml | 29 ------------- ...tack_network.yaml => openstack_infra.yaml} | 1 + .../tasks/{port.yml => baremetal_port.yml} | 0 .../tasks/neutron_port.yml | 9 ++++ .../roles/openstack_baremetal/tasks/node.yml | 43 +++++++++++++++---- .../roles/openstack_network/tasks/main.yml | 29 +++++++------ .../roles/openstack_network/tasks/port.yml | 9 ---- .../openstack_network/tasks/segment_range.yml | 6 +-- 8 files changed, 62 insertions(+), 64 deletions(-) delete mode 100644 ansible/playbooks/openstack_baremetal.yaml rename ansible/playbooks/{openstack_network.yaml => openstack_infra.yaml} (96%) rename ansible/roles/openstack_baremetal/tasks/{port.yml => baremetal_port.yml} (100%) create mode 100644 ansible/roles/openstack_baremetal/tasks/neutron_port.yml delete mode 100644 ansible/roles/openstack_network/tasks/port.yml diff --git a/ansible/playbooks/openstack_baremetal.yaml b/ansible/playbooks/openstack_baremetal.yaml deleted file mode 100644 index 5f4d6804b..000000000 --- a/ansible/playbooks/openstack_baremetal.yaml +++ /dev/null @@ -1,29 +0,0 @@ ---- -# Copyright (c) 2025 Rackspace Technology, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -- name: Openstack Network - hosts: ironic - connection: local - - pre_tasks: - - name: Fail if ENV variables are not set - ansible.builtin.fail: - msg: "Environment variable {{ item }} is not set. Exiting playbook." - when: lookup('env', item) == '' - loop: - - OS_CLOUD - - roles: - - role: openstack_baremetal diff --git a/ansible/playbooks/openstack_network.yaml b/ansible/playbooks/openstack_infra.yaml similarity index 96% rename from ansible/playbooks/openstack_network.yaml rename to ansible/playbooks/openstack_infra.yaml index 03be83ee6..71c8bcf41 100644 --- a/ansible/playbooks/openstack_network.yaml +++ b/ansible/playbooks/openstack_infra.yaml @@ -27,3 +27,4 @@ roles: - role: openstack_network + - role: openstack_baremetal diff --git a/ansible/roles/openstack_baremetal/tasks/port.yml b/ansible/roles/openstack_baremetal/tasks/baremetal_port.yml similarity index 100% rename from ansible/roles/openstack_baremetal/tasks/port.yml rename to ansible/roles/openstack_baremetal/tasks/baremetal_port.yml diff --git a/ansible/roles/openstack_baremetal/tasks/neutron_port.yml b/ansible/roles/openstack_baremetal/tasks/neutron_port.yml new file mode 100644 index 000000000..66cb84cf0 --- /dev/null +++ b/ansible/roles/openstack_baremetal/tasks/neutron_port.yml @@ -0,0 +1,9 @@ +--- + +- name: Create neutron port for network {{ port_info.neutron_network }} + openstack.cloud.port: + state: present + name: "{{ port_info.neutron_name }}" + mac_address: "{{ port_info.mac }}" + network: "{{ port_info.neutron_network }}" + when: port_info.neutron_name is defined diff --git a/ansible/roles/openstack_baremetal/tasks/node.yml b/ansible/roles/openstack_baremetal/tasks/node.yml index bdcf98049..c97c227ce 100644 --- a/ansible/roles/openstack_baremetal/tasks/node.yml +++ b/ansible/roles/openstack_baremetal/tasks/node.yml @@ -1,26 +1,51 @@ --- +- name: Extract MAC addresses + ansible.builtin.set_fact: + node_mac_addresses: >- + {{ + item.port_info + | map(attribute='port') + | map(attribute='mac') + | map('community.general.dict_kv', 'mac') + | list + }} + - name: Enroll infra node {{ item.name }} openstack.cloud.baremetal_node: name: "{{ item.name }}" driver: "{{ item.driver }}" driver_info: "{{ item.driver_info }}" - nics: "{{ item.nics }}" + nics: "{{ node_mac_addresses }}" state: present register: enrolled_node + +- name: Create baremetal port group for node {{ item.name }} + ansible.builtin.include_tasks: port_group.yml + loop: "{{ port_groups }}" + loop_control: + loop_var: port_group + vars: + node_id: "{{ enrolled_node.node.id }}" + port_groups: >- + {{ + item.port_info + | map(attribute='port_group') + | select('defined') + | list + }} + - name: Create baremetal ports for node {{ item.name }} - ansible.builtin.include_tasks: port.yml - loop: "{{ item.nics }}" + ansible.builtin.include_tasks: baremetal_port.yml + loop: "{{ node_mac_addresses }}" loop_control: loop_var: port_info vars: port_node_name: "{{ item.name }}" -- name: Create baremetal ports group for node {{ item.name }} - ansible.builtin.include_tasks: port_group.yml - loop: "{{ item.port_groups }}" +- name: Create neutron ports + ansible.builtin.include_tasks: neutron_port.yml + loop: "{{ item.port_info }}" loop_control: - loop_var: port_group - vars: - node_id: "{{ enrolled_node.node.id }}" + loop_var: port_info diff --git a/ansible/roles/openstack_network/tasks/main.yml b/ansible/roles/openstack_network/tasks/main.yml index 04b081c8c..5ea383285 100644 --- a/ansible/roles/openstack_network/tasks/main.yml +++ b/ansible/roles/openstack_network/tasks/main.yml @@ -18,14 +18,6 @@ loop_control: label: "{{ item.item.network_name }}" -- name: Create segment range - ansible.builtin.include_tasks: segment_range.yml - loop: "{{ network_segment_ranges }}" - loop_control: - loop_var: segment - vars: - item: "{{ segment }}" - - name: Create subnet pool ansible.builtin.include_tasks: subnet_pool.yml loop: "{{ subnet_pools }}" @@ -34,11 +26,20 @@ vars: item: "{{ subnet_pool }}" -- name: Create baremetal ports - ansible.builtin.include_tasks: port.yml - loop: "{{ baremetal_ports }}" +- name: Create fabric segment range + ansible.builtin.include_tasks: segment_range.yml + vars: + item: "{{ fabric_network_segment_range }}" + +- name: Create segment range + ansible.builtin.include_tasks: segment_range.yml + loop: "{{ network_segment_ranges.physical_networks }}" loop_control: - loop_var: network_ports + loop_var: physical_network vars: - ports: "{{ network_ports.ports }}" - network: "{{ network_ports.network }}" + item: + name: "{{ physical_network }}" + range_min: "{{ network_segment_ranges.range_min }}" + range_max: "{{ network_segment_ranges.range_max }}" + network_type: "{{ network_segment_ranges.network_type }}" + physical_network: "{{ physical_network }}" diff --git a/ansible/roles/openstack_network/tasks/port.yml b/ansible/roles/openstack_network/tasks/port.yml deleted file mode 100644 index 9655794c7..000000000 --- a/ansible/roles/openstack_network/tasks/port.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- name: Create neutron port for network {{ network }} - openstack.cloud.port: - state: present - name: "{{ item.name }}" - mac_address: "{{ item.mac_address }}" - network: "{{ network }}" - loop: "{{ ports }}" diff --git a/ansible/roles/openstack_network/tasks/segment_range.yml b/ansible/roles/openstack_network/tasks/segment_range.yml index 1ba84c166..58f0dc2f7 100644 --- a/ansible/roles/openstack_network/tasks/segment_range.yml +++ b/ansible/roles/openstack_network/tasks/segment_range.yml @@ -10,11 +10,11 @@ ansible.builtin.shell: > openstack network segment range create --shared - --network-type {{ item['network-type'] }} + --network-type {{ item.network_type }} --minimum {{ item.range_min }} --maximum {{ item.range_max }} - {% if item.get('physical-network', '') | length > 0 %} - --physical-network {{ item['physical-network'] }} + {% if item.physical_network is defined %} + --physical-network {{ item.physical_network }} {% endif %} {{ item.name }} when: segment_range_check.rc != 0