diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000000..ff7d7cc82c --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1 @@ +MD013: false diff --git a/playbooks/02-infra.yml b/playbooks/02-infra.yml index 735c23d181..14a07e8fa7 100644 --- a/playbooks/02-infra.yml +++ b/playbooks/02-infra.yml @@ -100,6 +100,12 @@ ansible.builtin.include_role: name: ci_nmstate + - name: Configure multus networks + when: + - cifmw_config_multus | default(false) | bool + ansible.builtin.include_role: + name: ci_multus + - name: Deploy Sushy Emulator and configure controller as hypervisor when: - cifmw_enable_virtual_baremetal_support | default(false) | bool diff --git a/roles/ci_multus/README.md b/roles/ci_multus/README.md index edc1a1ab89..1d7423a850 100644 --- a/roles/ci_multus/README.md +++ b/roles/ci_multus/README.md @@ -1,18 +1,25 @@ # ci_multus -Creates additional networks in a OCP cluster using NetworkAttachmentDefinition (NAD) resources. + +Creates additional networks in a OCP cluster using NetworkAttachmentDefinition +(NAD) resources. ## Parameters + * `cifmw_ci_multus_basedir`: (String) Base directory. Defaults to `cifmw_basedir` which defaults to `~/ci-framework-data`. * `cifmw_ci_multus_manifests_dir`: (String) Directory in where OCP manifests will be placed. Defaults to `"{{ cifmw_manifests | default(cifmw_ci_multus_basedir ~ '/artifacts/manifests') }}"`. * `cifmw_ci_multus_namespace`: (String) The namespace where OCP resources will be installed. Defaults to `ci-multus`. * `cifmw_ci_multus_ocp_hostname`: (String) The OCP inventory hostname. Used to gather network information specific to those nodes, mostly the interfaces. Defaults to `crc`. * `cifmw_ci_multus_cniversion`: (String) The CNI specification version used when creating the resource. Defaults to `0.3.1`. * `cifmw_ci_multus_default_nad_type`: (String) Default NAD type used when not specified by the network configuration. Defaults to `macvlan`. -* `cifmw_ci_multus_default_nad_ipam_type`: (String) Default NAD IPAM type to be used when not specified by the network configuration. Defaults to `whereabouts`. + `cifmw_ci_multus_default_nad_ipam_type`: (String) Default NAD IPAM type to be used when not specified by the network configuration. Defaults to `whereabouts`. * `cifmw_ci_multus_nad_list`: (List) List of NAD configuration to be created in destination OCP cluster. When not provided, `ci_multus` will build a list based on known cifmw variables (`cifmw_network_layout`, `crc_ci_bootstrap_networks_out`).Defaults to `[]`. * `cifmw_ci_multus_nad_extra_list`: (List) Additional list of NAD configuration to be created in destination OCP cluster. Defaults to `[]`. +In case the Multus NetworkAttachmentDefinition generated from the `cifmw_networking_env_definition` varible is not enough for the given purpose it is possible +to directly pass the configuration to be applied to each instance (OCP and/or unmanaged) by placing it in the `cifmw_ci_multus_nad_list` dict like this: + ## NAD configuration layout + The user can provide a list of NAD configuration as follow: ```YAML @@ -34,20 +41,17 @@ cifmw_ci_multus_nad_list: range_start: 100.65.4.1 range_end: 100.65.4.2 ``` -`cifmw_ci_multus_nad_list` can be passed directly, but if not given it will default, by that order, to the following: -1. The content of the `cifmw_network_layout` variable. -2. The content of the `crc_ci_bootstrap_networks_out` variable. -3. The content of the `crc_ci_bootstrap_networks_out` variable loaded from `/etc/ci/env`. - -If an additional NAD configuration needs to be configured, in addition to the content build from cifmw variables, the `cifmw_ci_multus_nad_extra_list` can be specified. ## Limitations + * Not all NetworkAttachmentDefinition types and parameters are supported by this role. * Not all IPAM configurations are supported by this role. * When consuming network info from CI variables, the user must provide the OCP host, using `cifmw_ci_multus_ocp_hostname` parameter, since the role doesn't perform a Node discovery on the OCP node. ## Examples -### 1 - Use of `cifmw_ci_multus_nad_list`: + +### 1 - Use of `cifmw_ci_multus_nad_list` + ```YAML - name: Configure additional networks using multus vars: @@ -63,18 +67,3 @@ If an additional NAD configuration needs to be configured, in addition to the co ansible.builtin.include_role: name: "ci_multus" ``` -### 2 - Content from `cifmw_network_layout`: -```YAML - - name: Configure additional networks using multus - vars: - cifmw_network_layout: - networks: - default: - iface: enps6s0 - mtu: 1500 - range: 192.168.122.0/24 - multus: - range: 192.168.122.30-192.168.122.70 - ansible.builtin.include_role: - name: "ci_multus" -``` diff --git a/roles/ci_multus/molecule/default/converge.yml b/roles/ci_multus/molecule/default/converge.yml index 8817d8aeff..822da38b2b 100644 --- a/roles/ci_multus/molecule/default/converge.yml +++ b/roles/ci_multus/molecule/default/converge.yml @@ -23,179 +23,186 @@ cifmw_openshift_kubeconfig: "{{ ansible_user_dir }}/.crc/machines/crc/kubeconfig" testpod_name: "pod-testnad" tasks: - - name: Add crc hostname with it's IP to /etc/hosts - become: true - ansible.builtin.lineinfile: - path: /etc/hosts - line: "192.168.130.11 crc" - - - name: Add the crc host dynamically - ansible.builtin.add_host: - name: crc - ansible_ssh_private_key_file: "{{ ansible_user_dir }}/.crc/machines/crc/id_ecdsa" - ansible_ssh_user: core - - - name: Fetch crc network facts - ansible.builtin.setup: - gather_subset: network - delegate_to: crc - delegate_facts: true - - - name: Prepare the network var for the role - ansible.builtin.set_fact: - crc_ci_bootstrap_networks_out: - networks: - default: - iface: "{{ hostvars.crc.ansible_default_ipv4.interface }}" - mtu: 1500 - range: 192.168.122.0/24 - multus: - range: 192.168.122.30-192.168.122.70 - cifmw_ci_multus_nad_extra_list: - - name: bgpnet1 - iface: bgpnet1_iface - type: interface - ipam: - type: whereabouts - range: 100.65.4.0/30 - range_start: 100.65.4.1 - range_end: 100.65.4.2 - - - name: Call ci_multus role - ansible.builtin.include_role: - name: "ci_multus" - - # Verify the run - - name: Fetch files stat results - ansible.builtin.stat: - path: >- - {{ - [ - ansible_user_dir, - 'ci-framework-data', - 'artifacts', - item - ] | ansible.builtin.path_join - }} - register: _ci_multus_molecule_stat_out - loop: - - manifests/ci_multus/ci_multus_nads.yml - - - name: Assert that all expected files exist - ansible.builtin.assert: - that: >- - _ci_multus_molecule_stat_out.results | - map(attribute="stat.exists") | - select("equalto", true) | - length == (_ci_multus_molecule_stat_out.results | length) - - - name: Fetch all files content - ansible.builtin.slurp: - path: "{{ item }}" - register: _ci_multus_molecule_slurp_out - loop: >- - {{ - _ci_multus_molecule_stat_out.results | - map(attribute="stat.path") - }} - - - name: Assert that all files contains proper YAML data - ansible.builtin.assert: - that: "item.content | b64decode | from_yaml_all | length > 0" - loop: "{{ _ci_multus_molecule_slurp_out.results }}" - loop_control: - label: "{{ item.source }}" - - - name: Check if NADs were created - kubernetes.core.k8s_info: - kubeconfig: "{{ cifmw_openshift_kubeconfig }}" - namespace: "{{ cifmw_ci_multus_namespace }}" - api_version: k8s.cni.cncf.io/v1 - kind: NetworkAttachmentDefinition - register: _ci_multus_molecule_nads_out - failed_when: >- - (_ci_multus_molecule_nads_out is not defined) or - (_ci_multus_molecule_nads_out is failed) or - (_ci_multus_molecule_nads_out.resources | length == 0) - - - name: Create a test pod to attach a network - kubernetes.core.k8s: - kubeconfig: "{{ cifmw_openshift_kubeconfig }}" - namespace: "{{ cifmw_ci_multus_namespace }}" - state: present - definition: - api_version: v1 - kind: Pod - metadata: + - name: Debug block + block: + - name: Add crc hostname with it's IP to /etc/hosts + become: true + ansible.builtin.lineinfile: + path: /etc/hosts + line: "192.168.130.11 crc" + + - name: Add the crc host dynamically + ansible.builtin.add_host: + name: crc + ansible_ssh_private_key_file: "{{ ansible_user_dir }}/.crc/machines/crc/id_ecdsa" + ansible_ssh_user: core + + - name: Fetch crc network facts + ansible.builtin.setup: + gather_subset: network + delegate_to: crc + delegate_facts: true + + - name: Prepare the network var for the role + ansible.builtin.set_fact: + cifmw_networking_env_definition: + instances: + crc: + name: crc + networks: + default: + interface_name: "{{ hostvars.crc.ansible_default_ipv4.interface }}" + network_name: default + networks: + default: + gw_v4: 192.168.122.1 + network_name: default + network_v4: 192.168.122.0/24 + tools: + multus: + ipv4_ranges: + - end: 172.20.1.70 + start: 172.20.1.30 + + - name: Call ci_multus role + ansible.builtin.include_role: + name: "ci_multus" + + # Verify the run + - name: Fetch files stat results + ansible.builtin.stat: + path: >- + {{ + [ + ansible_user_dir, + 'ci-framework-data', + 'artifacts', + item + ] | ansible.builtin.path_join + }} + register: _ci_multus_molecule_stat_out + loop: + - manifests/ci_multus/ci_multus_nads.yml + + - name: Assert that all expected files exist + ansible.builtin.assert: + that: >- + _ci_multus_molecule_stat_out.results | + map(attribute="stat.exists") | + select("equalto", true) | + length == (_ci_multus_molecule_stat_out.results | length) + + - name: Fetch all files content + ansible.builtin.slurp: + path: "{{ item }}" + register: _ci_multus_molecule_slurp_out + loop: >- + {{ + _ci_multus_molecule_stat_out.results | + map(attribute="stat.path") + }} + + - name: Assert that all files contains proper YAML data + ansible.builtin.assert: + that: "item.content | b64decode | from_yaml_all | length > 0" + loop: "{{ _ci_multus_molecule_slurp_out.results }}" + loop_control: + label: "{{ item.source }}" + + - name: Check if NADs were created + kubernetes.core.k8s_info: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + namespace: "{{ cifmw_ci_multus_namespace }}" + api_version: k8s.cni.cncf.io/v1 + kind: NetworkAttachmentDefinition + register: _ci_multus_molecule_nads_out + failed_when: >- + (_ci_multus_molecule_nads_out is not defined) or + (_ci_multus_molecule_nads_out is failed) or + (_ci_multus_molecule_nads_out.resources | length == 0) + + - name: Create a test pod to attach a network + kubernetes.core.k8s: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + namespace: "{{ cifmw_ci_multus_namespace }}" + state: present + definition: + api_version: v1 + kind: Pod + metadata: + name: "{{ testpod_name }}" + annotations: + k8s.v1.cni.cncf.io/networks: default + spec: + containers: + - name: testnad + image: quay.rdoproject.org/openstack-k8s-operators/alpine:latest + imagePullPolicy: Always + command: + - "/bin/ash" + - "-c" + - "trap : TERM INT; sleep infinity & wait" + wait: true + wait_sleep: 10 + wait_timeout: 300 + wait_condition: + type: Ready + status: "True" + register: _ci_multus_molecule_test_pod_out + + - name: Assert that test pod has the additional network + ansible.builtin.assert: + that: + - _ci_multus_molecule_test_pod_out.result.metadata.annotations[ + 'k8s.v1.cni.cncf.io/networks'] == "default" + + - name: Delete test pod + kubernetes.core.k8s: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + api_key: "{{ cifmw_openshift_token | default(omit)}}" + context: "{{ cifmw_openshift_context | default(omit)}}" + namespace: "{{ cifmw_ci_multus_namespace }}" + state: absent + api_version: v1 + kind: Pod name: "{{ testpod_name }}" - annotations: - k8s.v1.cni.cncf.io/networks: default - spec: - containers: - - name: testnad - image: quay.rdoproject.org/openstack-k8s-operators/alpine:latest - imagePullPolicy: Always - command: - - "/bin/ash" - - "-c" - - "trap : TERM INT; sleep infinity & wait" - wait: true - wait_sleep: 10 - wait_timeout: 300 - wait_condition: - type: Ready - status: "True" - register: _ci_multus_molecule_test_pod_out - - - name: Assert that test pod has the additional network - ansible.builtin.assert: - that: - - _ci_multus_molecule_test_pod_out.result.metadata.annotations[ - 'k8s.v1.cni.cncf.io/networks'] == "default" - - - name: Delete test pod - kubernetes.core.k8s: - kubeconfig: "{{ cifmw_openshift_kubeconfig }}" - api_key: "{{ cifmw_openshift_token | default(omit)}}" - context: "{{ cifmw_openshift_context | default(omit)}}" - namespace: "{{ cifmw_ci_multus_namespace }}" - state: absent - api_version: v1 - kind: Pod - name: "{{ testpod_name }}" - - - name: Call cleanup - ansible.builtin.import_role: - name: ci_multus - tasks_from: cleanup.yml - - - name: Check if NADs were deleted - kubernetes.core.k8s_info: - kubeconfig: "{{ cifmw_openshift_kubeconfig }}" - namespace: "{{ cifmw_ci_multus_namespace }}" - api_version: k8s.cni.cncf.io/v1 - kind: NetworkAttachmentDefinition - register: _ci_multus_molecule_nads_cleanup_out - failed_when: >- - (_ci_multus_molecule_nads_cleanup_out is not defined) or - (_ci_multus_molecule_nads_cleanup_out is failed) or - (_ci_multus_molecule_nads_cleanup_out.resources | length > 0) - - - name: Get all namespaces - kubernetes.core.k8s_info: - kubeconfig: "{{ cifmw_openshift_kubeconfig }}" - api_key: "{{ cifmw_openshift_token | default(omit)}}" - context: "{{ cifmw_openshift_context | default(omit)}}" - kind: Namespace - register: _ci_multus_molecule_ns_out - - - name: Assert that multus namespace is absent - vars: - ns_names: >- - {{ - _ci_multus_molecule_ns_out.resources | - default([]) | - map(attribute='metadata.name') - }} - ansible.builtin.assert: - that: "cifmw_ci_multus_namespace not in ns_names" + + - name: Call cleanup + ansible.builtin.import_role: + name: ci_multus + tasks_from: cleanup.yml + + - name: Check if NADs were deleted + kubernetes.core.k8s_info: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + namespace: "{{ cifmw_ci_multus_namespace }}" + api_version: k8s.cni.cncf.io/v1 + kind: NetworkAttachmentDefinition + register: _ci_multus_molecule_nads_cleanup_out + failed_when: >- + (_ci_multus_molecule_nads_cleanup_out is not defined) or + (_ci_multus_molecule_nads_cleanup_out is failed) or + (_ci_multus_molecule_nads_cleanup_out.resources | length > 0) + + - name: Get all namespaces + kubernetes.core.k8s_info: + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + api_key: "{{ cifmw_openshift_token | default(omit)}}" + context: "{{ cifmw_openshift_context | default(omit)}}" + kind: Namespace + register: _ci_multus_molecule_ns_out + + - name: Assert that multus namespace is absent + vars: + ns_names: >- + {{ + _ci_multus_molecule_ns_out.resources | + default([]) | + map(attribute='metadata.name') + }} + ansible.builtin.assert: + that: "cifmw_ci_multus_namespace not in ns_names" + rescue: + - name: "List all known variables and facts" + debug: + var: hostvars[inventory_hostname] diff --git a/roles/ci_multus/tasks/extract_ci_data.yml b/roles/ci_multus/tasks/extract_ci_data.yml deleted file mode 100644 index b146122851..0000000000 --- a/roles/ci_multus/tasks/extract_ci_data.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -# Copyright Red Hat, Inc.the -# All Rights Reserved. -# -# 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: Extract data from network env file if available - when: - - cifmw_network_layout is not defined - - crc_ci_bootstrap_networks_out is not defined - block: - - name: Check for CI env directory - when: crc_ci_bootstrap_networks_out is not defined - register: _cifmw_ci_multus_ci_env_stat - ansible.builtin.stat: - path: /etc/ci/env - - - name: Load network env file - when: _cifmw_ci_multus_ci_env_stat.stat.exists - ansible.builtin.include_vars: - dir: /etc/ci/env/ - -- name: Gather network layout from OCP host or default networks - ansible.builtin.set_fact: - _cifmw_ci_multus_net_info: >- - {{ - cifmw_network_layout[cifmw_ci_multus_ocp_hostname] | default({}) | - combine( cifmw_network_layout['networks'], recursive=true) - if cifmw_network_layout is defined else - (crc_ci_bootstrap_networks_out[cifmw_ci_multus_ocp_hostname] | default({})| - combine( crc_ci_bootstrap_networks_out['networks'], recursive=true) - ) - }} - -- name: Build list of NetworkAttachmentDefinition - ansible.builtin.set_fact: - cifmw_ci_multus_nad_list: >- - {{ - cifmw_ci_multus_nad_list + - [{ - 'name': item.key, - 'iface': item.value.iface, - 'ipam': - { - 'range': item.value.range, - 'range_start': item.value.multus.range | split('-') | first, - 'range_end': item.value.multus.range | split('-') | last - } - }] - }} - loop: "{{ _cifmw_ci_multus_net_info | dict2items }}" diff --git a/roles/ci_multus/tasks/main.yml b/roles/ci_multus/tasks/main.yml index 310f9f1ea0..205c5a9ecf 100644 --- a/roles/ci_multus/tasks/main.yml +++ b/roles/ci_multus/tasks/main.yml @@ -19,11 +19,56 @@ path: "{{ cifmw_ci_multus_manifests_dir }}" state: directory -- name: Build NetAttDef list from ci environment +- name: Build Network Attach Difinition list from cifmw_networking_env_definition when: - cifmw_ci_multus_nad_list | length == 0 - ansible.builtin.include_tasks: extract_ci_data.yml + block: + - name: Load Networking Environment Definition + ansible.builtin.import_role: + name: networking_mapper + tasks_from: load_env_definition.yml + - name: Gather network layout from OCP host or default networks + ansible.builtin.set_fact: + _cifmw_ci_multus_net_info: >- + {{ + ( + cifmw_networking_env_definition.instances[cifmw_ci_multus_ocp_hostname].networks | default({})| + combine( cifmw_networking_env_definition['networks'], recursive=true) + ) + }} + + - name: Reject any networks without Multus configured + ansible.builtin.debug: + msg: "tmp" + + - name: Apply allow list filter if defined to list of networks to configure + ansible.builtin.debug: + msg: "tmp" + + - name: Apply deny list filter if defined to list of networks to configure + ansible.builtin.debug: + msg: "tmp" + + - name: Build list of NetworkAttachmenktDefinition + ansible.builtin.set_fact: + cifmw_ci_multus_nad_list: >- + {{ + cifmw_ci_multus_nad_list + + [{ + 'name': item.key, + 'iface': item.value.iface, + 'ipam': + { + 'range': item.value.range, + 'range_start': item.value.multus.range | split('-') | first, + 'range_end': item.value.multus.range | split('-') | last + } + }] + }} + loop: "{{ _cifmw_ci_multus_net_info | dict2items }}" + +# Note: Replace extra list with patch mech - name: Create network attachment definitions in manifest dir vars: _cifmw_ci_multus_nad_list: "{{ cifmw_ci_multus_nad_list + cifmw_ci_multus_nad_extra_list }}" diff --git a/zuul.d/edpm_multinode.yaml b/zuul.d/edpm_multinode.yaml index eb429f8548..2fc67fa8f5 100644 --- a/zuul.d/edpm_multinode.yaml +++ b/zuul.d/edpm_multinode.yaml @@ -445,23 +445,74 @@ parent: podified-multinode-edpm-deployment-crc-bootstrap-staging vars: cifmw_enable_virtual_baremetal_support: true + cifmw_config_nmstate: true + cifmw_config_multus: true + cifmw_ci_nmstate_instance_config: + controller: + interfaces: + - name: "{{ cifmw_networking_env_definition.instances['controller'].networks['baremetal'].interface_name | default(omit) }}" + type: ethernet + state: up + + - name: baremetal + type: linux-bridge + state: up + bridge: + options: + stp: + enabled: false + port: + - name: "{{ cifmw_networking_env_definition.instances['controller'].networks['baremetal'].interface_name | default(omit) }}" + stp-hairpin-mode: false + stp-path-cost: 100 + stp-priority: 32 + ipv4: + address: + - ip: "{{ cifmw_networking_mapper_definition_patch_02_bmaas_net.instances.controller.networks.baremetal.ip }}" + prefix-length: 24 + enabled: true + ipv6: + enabled: false + cifmw_install_yamls_vars_patch_01_ironic_ci_base: + INSTALL_NMSTATE: false cifmw_networking_mapper_definition_patch_02_bmaas_net: networks: baremetal: network: "172.20.1.0/24" - gateway: "172.20.1.1" mtu: 1500 + tools: + multus: + ipv4_ranges: + - start: 172.20.1.30 + end: 172.20.1.70 instances: controller: networks: baremetal: ip: "172.20.1.11" - skip-nm-configuration: true crc: networks: baremetal: ip: "172.20.1.5" - skip-nm-configuration: true + cifmw_libvirt_manager_configuration: + vms: + compute: + uefi: true + amount: 2 + root_part_id: 4 + disk_file_name: "blank" + disksize: 30 + memory: 4 + cpus: 4 + nets: + - baremetal + networks: + baremetal: | + + baremetal + + + + run: - ci/playbooks/edpm/run.yml - - ci/playbooks/edpm/fail.yml diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 193a6e7ad2..cf016f9037 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -2,106 +2,5 @@ github-check: jobs: - noop - - cifmw-pod-ansible-test - - cifmw-pod-k8s-snippets-source - - cifmw-pod-pre-commit - - cifmw-pod-zuul-files - - cifmw-content-provider-build-images - - cifmw-edpm-build-images - - cifmw-multinode-kuttl - - cifmw-tcib - - cifmw-architecture-validate-hci - - ci-framework-openstack-meta-content-provider - - build-push-container-cifmw-client - - cifmw-molecule-artifacts - - cifmw-molecule-build_containers - - cifmw-molecule-build_openstack_packages - - cifmw-molecule-build_push_container - - cifmw-molecule-cert_manager - - cifmw-molecule-ci_gen_kustomize_values - - cifmw-molecule-ci_local_storage - - cifmw-molecule-ci_lvms_storage - - cifmw-molecule-ci_metallb + - podified-multinode-edpm-deployment-crc-bootstrap-staging-ironic - cifmw-molecule-ci_multus - - cifmw-molecule-ci_netconfig - - cifmw-molecule-ci_network - - cifmw-molecule-ci_nmstate - - cifmw-molecule-ci_setup - - cifmw-molecule-cifmw_block_device - - cifmw-molecule-cifmw_ceph_client - - cifmw-molecule-cifmw_ceph_spec - - cifmw-molecule-cifmw_cephadm - - cifmw-molecule-cifmw_create_admin - - cifmw-molecule-cifmw_external_dns - - cifmw-molecule-cifmw_ntp - - cifmw-molecule-cifmw_test_role - - cifmw-molecule-compliance - - cifmw-molecule-config_drive - - cifmw-molecule-copy_container - - cifmw-molecule-deploy_bmh - - cifmw-molecule-devscripts - - cifmw-molecule-discover_latest_image - - cifmw-molecule-dlrn_promote - - cifmw-molecule-dlrn_report - - cifmw-molecule-dnsmasq - - cifmw-molecule-edpm_build_images - - cifmw-molecule-edpm_deploy - - cifmw-molecule-edpm_deploy_baremetal - - cifmw-molecule-edpm_kustomize - - cifmw-molecule-edpm_prepare - - cifmw-molecule-env_op_images - - cifmw-molecule-hci_prepare - - cifmw-molecule-hive - - cifmw-molecule-idrac_configuration - - cifmw-molecule-install_ca - - cifmw-molecule-install_openstack_ca - - cifmw-molecule-install_yamls - - cifmw-molecule-kustomize_deploy - - cifmw-molecule-libvirt_manager - - cifmw-molecule-manage_secrets - - cifmw-molecule-mirror_registry - - cifmw-molecule-nat64_appliance - - cifmw-molecule-networking_mapper - - cifmw-molecule-openshift_adm - - cifmw-molecule-openshift_login - - cifmw-molecule-openshift_obs - - cifmw-molecule-openshift_provisioner_node - - cifmw-molecule-openshift_setup - - cifmw-molecule-operator_build - - cifmw-molecule-operator_deploy - - cifmw-molecule-os_must_gather - - cifmw-molecule-os_net_setup - - cifmw-molecule-ovirt - - cifmw-molecule-pkg_build - - cifmw-molecule-podman - - cifmw-molecule-polarion - - cifmw-molecule-registry_deploy - - cifmw-molecule-repo_setup - - cifmw-molecule-reportportal - - cifmw-molecule-reproducer - - cifmw-molecule-rhol_crc - - cifmw-molecule-run_hook - - cifmw-molecule-set_openstack_containers - - cifmw-molecule-shiftstack - - cifmw-molecule-ssh_jumper - - cifmw-molecule-sushy_emulator - - cifmw-molecule-switch_config - - cifmw-molecule-tempest - - cifmw-molecule-test_deps - - cifmw-molecule-test_operator - - cifmw-molecule-tofu - - cifmw-molecule-update - - cifmw-molecule-update_containers - - cifmw-molecule-validations - - cifmw-molecule-virtualbmc - github-experimental-trigger: - jobs: - - downstream-va-hci-trigger-job - - downstream-uni02beta-upstream-trigger-job - github-post: - jobs: - - build-push-container-cifmw-client-post - name: openstack-k8s-operators/ci-framework - templates: - - podified-multinode-edpm-ci-framework-pipeline - - data-plane-adoption-ci-framework-pipeline