Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions ci/scenarios/sno-1-bm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# sno-1-bm Scenario

## Overview

A Single Node OpenShift (SNO) scenario designed to test OpenStack Ironic bare
metal provisioning with 1 dedicated Ironic node using iPXE network boot. This
scenario validates the complete OpenStack bare metal lifecycle including node
enrollment, provisioning, and Tempest testing.

## Architecture

<!-- markdownlint-disable MD013 -->
```mermaid
graph TD
Internet[("Internet")]
Router{{"Neutron<br/>Router"}}

MachineNet["Machine Network<br/>192.168.32.0/24"]
CtlPlane["CtlPlane Network<br/>192.168.122.0/24"]
VLANNets["VLAN Trunk Networks<br/>Internal API: 172.17.0.0/24<br/>Storage: 172.18.0.0/24<br/>Tenant: 172.19.0.0/24"]
IronicNet["Ironic Network<br/>172.20.1.0/24"]

Controller["Controller<br/>192.168.32.254<br/>DNS/HAProxy"]
Master["SNO Master<br/>192.168.32.10"]
IronicNodes["Ironic Node x1<br/>Virtual Baremetal"]

LVM["TopoLVM<br/>20GB"]
CinderVols["Cinder Volumes x3<br/>20GB each"]

Internet --- Router

Router --- MachineNet
Router --- CtlPlane
Router --- VLANNets
Router --- IronicNet

MachineNet --- Controller
MachineNet --- Master
CtlPlane --- Master
VLANNets --- Master
IronicNet --- Master
IronicNet --- IronicNodes

Master --- LVM
Master --- CinderVols

style Controller fill:#4A90E2,stroke:#2E5C8A,stroke-width:3px,color:#fff
style Master fill:#F5A623,stroke:#C87D0E,stroke-width:3px,color:#fff
style IronicNodes fill:#9B59B6,stroke:#6C3A82,stroke-width:2px,color:#fff
style Router fill:#27AE60,stroke:#1E8449,stroke-width:3px,color:#fff
```
<!-- markdownlint-enable MD013 -->

### Component Details

- **Controller**: Hotstack controller providing DNS, load balancing, and
orchestration services
- **SNO Master**: Single-node OpenShift cluster running the complete OpenStack
control plane
- **Ironic Node**: 1 virtual bare metal node for testing Ironic provisioning workflows

## Networks

- **machine-net**: 192.168.32.0/24 (OpenShift cluster network)
- **ctlplane-net**: 192.168.122.0/24 (OpenStack control plane)
- **internal-api-net**: 172.17.0.0/24 (OpenStack internal services)
- **storage-net**: 172.18.0.0/24 (Storage backend communication)
- **tenant-net**: 172.19.0.0/24 (Tenant network traffic)
- **ironic-net**: 172.20.1.0/24 (Bare metal provisioning network)

## OpenStack Services

This scenario deploys a comprehensive OpenStack environment:

### Core Services

- **Keystone**: Identity service with LoadBalancer on Internal API
- **Nova**: Compute service with Ironic driver for bare metal
- **Neutron**: Networking service with OVN backend
- **Glance**: Image service with Swift backend
- **Swift**: Object storage service
- **Placement**: Resource placement service

### Bare Metal Services

- **Ironic**: Bare metal provisioning service
- **Ironic Inspector**: Hardware inspection service
- **Ironic Neutron Agent**: Network management for bare metal

## Usage

```bash
# Deploy the scenario
ansible-playbook -i inventory.yml bootstrap.yml \
-e @scenarios/sno-1-bm/bootstrap_vars.yml \
-e @~/cloud-secrets.yaml

# Run comprehensive tests
ansible-playbook -i inventory.yml 06-test-operator.yml \
-e @scenarios/sno-1-bm/bootstrap_vars.yml \
-e @~/cloud-secrets.yaml
```

## Configuration Files

- `bootstrap_vars.yml`: Infrastructure and OpenShift configuration.
- `automation-vars.yml`: Hotloop deployment stages
- `heat_template_ipxe.yaml`: OpenStack infrastructure template (iPXE network boot)
- `manifests/control-plane/control-plane.yaml`: OpenStack service configuration
- `test-operator/automation-vars.yml`: Comprehensive test automation
- `test-operator/tempest-tests.yml`: Tempest test specifications
139 changes: 139 additions & 0 deletions ci/scenarios/sno-1-bm/automation-vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
stages:
- name: TopoLVM Dependencies
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/topolvm-deps-stages.yaml.j2")
}}

- name: Dependencies
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/deps-stages.yaml.j2")
}}

- name: Cinder LVM
stages: >-
{{
lookup("ansible.builtin.file",
"common/stages/cinder-lvm-label-stages.yaml")
}}

- name: TopoLVM
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/topolvm-stages.yaml.j2")
}}

- name: OLM Openstack
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/olm-openstack-stages.yaml.j2")
}}

- name: NodeNetworkConfigurationPolicy (nncp)
documentation: |
Apply node network configuration policies to configure host networking.
Waits for all policies to be successfully configured.
j2_manifest: manifests/control-plane/networking/nncp.yaml.j2
wait_conditions:
- >-
oc wait -n openstack nncp -l osp/nncm-config-type=standard
--for jsonpath='{.status.conditions[0].reason}'=SuccessfullyConfigured
--timeout=180s

- name: NetworkAttchmentDefinition (NAD)
documentation: |
Create network attachment definitions for OpenStack services.
Defines additional network interfaces for pods.
manifest: manifests/control-plane/networking/nad.yaml

- name: MetalLB - L2Advertisement and IPAddressPool
documentation: |
Configure MetalLB load balancer with IP address pools and L2 advertisements.
Enables external access to OpenStack services.
manifest: manifests/control-plane/networking/metallb.yaml

- name: OpenstackControlPlane
documentation: |
Deploy the OpenStack control plane with all core services.
Waits for the control plane to be fully ready before proceeding.
j2_manifest: manifests/control-plane/control-plane.yaml.j2
wait_conditions:
- >-
oc -n openstack wait openstackcontrolplanes.core.openstack.org controlplane
--for condition=OpenStackControlPlaneDNSReadyCondition --timeout=600s

- name: Extra DNS LoadBalancer on Ironic network
documentation: |
Deploy additional DNS service on the Ironic network for bare metal provisioning.
Provides DNS resolution for ironic nodes during deployment and inspection.
manifest: manifests/control-plane/dnsmasq-dns-ironic.yaml
wait_conditions:
- >-
oc wait -n openstack service dnsmasq-dns-ironic
--for jsonpath='.status.loadBalancer' --timeout=60s

- name: Wait for OpenstackControlPlane
documentation: |
Wait for the OpenStack control plane to be fully ready and operational.
Ensures all services are running before proceeding with additional configurations.
wait_conditions:
- >-
oc wait -n openstack openstackcontrolplane controlplane
--for condition=Ready --timeout=30m

- name: Update openstack-operators OLM
stages: >-
{{
lookup('ansible.builtin.template',
'common/stages/openstack-olm-update.yaml.j2')
}}
run_conditions:
- >-
{{
openstack_operators_update is defined and
openstack_operators_update | bool
}}

- name: Wait for condition MinorUpdateAvailable True
documentation: |
Wait for OpenStack version to indicate a minor update is available.
Required before proceeding with version updates.
wait_conditions:
- >-
oc -n openstack wait openstackversions.core.openstack.org controlplane
--for=condition=MinorUpdateAvailable=True --timeout=10m
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"

- name: "Minor update :: Create OpenStackVersion patch"
documentation: |
This creates a patch file `{{ manifests_dir }}/patches/openstack_version_patch.yaml`
If `openstack_update_custom_images` is defined it will populate the customContainerImages
in the OpenstackVersion YAML patch.
shell: >-
{{
lookup('ansible.builtin.template',
'common/scripts/create_openstack_version_patch.sh.j2')
}}
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"

- name: "Minor update :: Update the target version in the OpenStackVersion custom resource (CR)"
documentation: |
The `hotstack-openstack-version-patch` script will get the `availableVersion`
and us it to replace the string `__TARGET_VERSION__` in the patch file and
apply the patch using `oc patch` command.
command: >-
hotstack-openstack-version-patch --namespace openstack --name controlplane
--file {{ manifests_dir }}/patches/openstack_version_patch.yaml
wait_conditions:
- oc -n openstack wait openstackversions.core.openstack.org controlplane
--for=condition=Ready --timeout=10m
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"
57 changes: 57 additions & 0 deletions ci/scenarios/sno-1-bm/bootstrap_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
os_cloud: default
os_floating_network: public
os_router_external_network: public

scenario: sno-1-bm
scenario_dir: scenarios
stack_template_path: "{{ scenario_dir }}/{{ scenario }}/heat_template_ipxe.yaml"
automation_vars_file: "{{ scenario_dir }}/{{ scenario }}/automation-vars.yml"
test_operator_automation_vars_file: "{{ scenario_dir }}/{{ scenario }}/test-operator/automation-vars.yml"

openstack_operators_image: quay.io/openstack-k8s-operators/openstack-operator-index:latest
openstack_operator_channel: alpha
openstack_operator_starting_csv: null

openshift_version: stable-4.18

ntp_servers: []
dns_servers:
- 172.31.0.129

pull_secret_file: ~/pull-secret.txt

ovn_k8s_gateway_config_host_routing: true
enable_iscsi: true
enable_multipath: true

cinder_volume_pvs:
- /dev/vdc
- /dev/vdd
- /dev/vde

# Nova console recorder NFS settings
nova_console_recorder_nfs_server: controller-0.openstack.lab
nova_console_recorder_nfs_path: /export/nova-console-recordings

stack_name: "hs-{{ scenario }}-{{ zuul.build[:8] | default('no-zuul') }}"
stack_parameters:
# On misconfigured clouds, uncomment these to avoid issues.
# Ref: https://access.redhat.com/solutions/7059376
# net_value_specs:
# mtu: 1442
dns_servers: "{{ dns_servers }}"
ntp_servers: "{{ ntp_servers }}"
controller_ssh_pub_key: "{{ controller_ssh_pub_key | default('') }}"
router_external_network: "{{ os_router_external_network | default('public') }}"
floating_ip_network: "{{ os_floating_network | default('public') }}"
controller_params:
image: hotstack-controller
flavor: hotstack.small
ocp_master_params:
image: ipxe-boot-usb
flavor: hotstack.xxlarge
ironic_params:
image: CentOS-Stream-GenericCloud-9
cd_image: sushy-tools-blank-image
flavor: hotstack.medium
Loading
Loading