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
18 changes: 18 additions & 0 deletions ci/nmstate_validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

set -x

if ! command -v nmstatectl; then
echo "nmstatectl is not installed"
exit 0
fi

if ! command -v yq; then
echo "yq is not installed"
exit 0
fi

for document_idx in $(yq '.spec.desiredState | document_index' "$1" | grep -v "\---")
do
yq ".spec.desiredState | select(document_index == $document_idx)" "$1" | nmstatectl -q validate --
done
5 changes: 3 additions & 2 deletions scenarios/sno-nxsw/heat_template.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
heat_template_version: rocky

description: >
Heat template to set up SNO (Single Node OpenShift) infrastructure, 1x Controller, 1x OCP Master (no ironic nodes)
description: |
Heat template to set up SNO (Single Node OpenShift) infrastructure,
1x Controller, 1x OCP Master, 1x Switch, 2x Ironic nodes

parameters:
dns_servers:
Expand Down
133 changes: 133 additions & 0 deletions scenarios/sno-veos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# SNO-NXSW Scenario

## Overview

The `sno-veos` scenario is a Single Node OpenShift (SNO) deployment scenario
for HotStack that deploys OpenStack on OpenShift with ironic bare metal
provisioning capabilities and network switch integration.

## Architecture

This scenario provisions:

- **1x Controller Node**: Management and DNS/DHCP services
- **1x OpenShift Master Node**: Single node OpenShift cluster running OpenStack services
- **1x Switch Node**: vEOS Lab switch with trunk ports for tenant VLAN networks
- **2x Ironic Nodes**: Virtual bare metal nodes for testing Ironic provisioning workflows

## Features

- **Complete OpenStack Stack**: Full OpenStack deployment with ironic bare
metal service
- **Network Switch Integration**: Automated switch configuration with
Zero Prov (??? Arista vEOS) and NGS (Networking Generic Switch)
- **Complete Networking**: All OpenStack service networks with dedicated
ironic networks
- **SNO Deployment**: Single node OpenShift optimized for OpenStack services
- **Development Ready**: Ideal for testing and development environments
- **Bare Metal Provisioning**: Ironic service with 2 nodes for testing bare
metal workflows

## Networks

- **machine-net**: 192.168.32.0/24 - External access network
- **ctlplane-net**: 192.168.122.0/24 - Control plane network
- **internal-api-net**: 172.17.0.0/24 - OpenStack internal API network
- **storage-net**: 172.18.0.0/24 - Storage network
- **tenant-net**: 172.19.0.0/24 - Tenant network for OpenStack workloads
- **ironic-net**: 172.20.1.0/24 - Ironic network for bare metal provisioning
- **tenant-vlan103**: 172.20.3.0/24 - Tenant VLAN network (VLAN 103)
- **tenant-vlan104**: 172.20.4.0/24 - Tenant VLAN network (VLAN 104)
- **ironic0-br-net**: 172.20.5.0/29 - Ironic0 bridge network
- **ironic1-br-net**: 172.20.5.8/29 - Ironic1 bridge network

## Switch Instance Configuration

The switch instance provides network switching capabilities with the following
interface configuration:

### Network Interface Summary

```text
Switch Instance:
├── eth0: machine-net (management interface)
├── eth1: trunk (ironic:101, tenant-vlan103:103, tenant-vlan104:104)
├── eth2: ironic0-br-net (ironic bridge network)
└── eth3: ironic1-br-net (ironic bridge network)
```

### VLAN Mapping

- **VLAN 101**: ironic (172.20.1.0/24)
- **VLAN 102**: Default native VLAN
- **VLAN 103**: tenant-vlan103 (172.20.3.0/24)
- **VLAN 104**: tenant-vlan104 (172.20.4.0/24)

The switch uses the `nxsw` image and provides dual trunk ports for redundancy
and high availability.

### POAP (Power-On Auto Provisioning)

POAP is a Cisco NX-OS feature that automates the initial configuration of
network switches. When the switch boots up, it automatically:

1. **Downloads Configuration**: Fetches the switch configuration from a
TFTP/HTTP server
2. **Applies Settings**: Automatically configures interfaces, VLANs, and
network settings
3. **Enables Services**: Activates required network services (NETCONF, LACP, LLDP)
4. **Validates Setup**: Performs integrity checks using MD5 checksums

In this scenario, POAP enables zero-touch deployment of the NX-OS switch with pre-configured:

- **Interface Configuration**: Trunk and access ports for tenant VLANs
- **VLAN Setup**: VLANs for network segmentation
- **Management Settings**: IP addressing, DNS, and routing configuration
- **Security**: User accounts and access control

## Ironic Nodes

The scenario includes 2 virtual bare metal nodes for testing Ironic provisioning:

### Ironic Node 0

- **Network**: ironic0-br-net (172.20.5.0/29)
- **Purpose**: Bare metal provisioning testing
- **Configuration**: Virtual media boot capable with sushy-tools

### Ironic Node 1

- **Network**: ironic1-br-net (172.20.5.8/29)
- **Purpose**: Bare metal provisioning testing
- **Configuration**: Virtual media boot capable with sushy-tools

## Usage

This scenario is ideal for:

- Testing OpenStack deployments with neutron ML2 plugins
- Validating bare metal provisioning workflows with Ironic
- Network switch integration testing with OpenStack
- Development and testing of networking-generic-switch functionality

## Files

- `bootstrap_vars.yml`: Main configuration variables
- `heat_template.yaml`: OpenStack Heat template for infrastructure
- `automation-vars.yml`: Automation pipeline definition
- `manifests/`: OpenShift/Kubernetes manifests
- `test-operator/`: Test automation configuration

## Upload switch image to cloud

```bash
openstack image create vEOS-lab-4.34.1F \
--disk-format qcow2 \
--file vEOS-lab-4.34.1F.qcow2 \
--property hw_video_model=none
```

## Deployment

Follow the standard HotStack deployment process with this scenario by setting
the scenario name to `sno-veos` in your deployment configuration.
122 changes: 122 additions & 0 deletions scenarios/sno-veos/automation-vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
stages:
- 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)
manifest: manifests/networking/nncp.yaml
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)
manifest: manifests/networking/nad.yaml

- name: MetalLB - L2Advertisement and IPAddressPool
manifest: manifests/networking/metallb.yaml

- name: Netconfig
manifest: manifests/networking/netconfig.yaml

- name: NGS config (Networking Generic Switch)
manifest: manifests/ngs/config.yaml
wait_conditions:
- >-
oc wait -n openstack secret neutron-switch-config
--for jsonpath='{.metadata.name}'=neutron-switch-config
--timeout=30s

- name: Openstack Version
manifest: manifests/openstack-version.yaml
patches:
- path: spec.customContainerImages
value: "{{ customContainerImages }}"
wait_conditions:
- >-
oc wait -n openstack openstackversions.core.openstack.org controlplane
--for condition=Initialized --timeout=30m
run_conditions:
- >-
{{ customContainerImages is defined and customContainerImages | length > 0 }}

- name: OpenstackControlPlane
manifest: manifests/control-plane.yaml
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
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 }}"
62 changes: 62 additions & 0 deletions scenarios/sno-veos/bootstrap_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
os_cloud: default
os_floating_network: public
os_router_external_network: public

controller_ssh_pub_key: "{{ lookup('ansible.builtin.file', '~/.ssh/id_rsa.pub') }}"

scenario: sno-veos
scenario_dir: scenarios
stack_template_path: "{{ scenario_dir }}/{{ scenario }}/heat_template.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:
- 8.8.8.8
- 8.8.4.4

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

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 }}"
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
switch_params:
image: vEOS64-lab-4.34.1F
flavor: hotstack.large
ironic_params:
image: CentOS-Stream-GenericCloud-9
cd_image: sushy-tools-blank-image
flavor: hotstack.medium

customContainerImages:
neutronAPIImage: quay.io/steveb/openstack-neutron-server:18.0.9-2.1751380459-ngs
Loading