Skip to content

Commit

Permalink
[ci_multus] Refactor role
Browse files Browse the repository at this point in the history
The ci_multus role was created but unused, this patch refreshes it as we
will begin to use it in the new job to test Ironic.
  • Loading branch information
lewisdenny committed Oct 30, 2024
1 parent ce1929a commit e9e1037
Show file tree
Hide file tree
Showing 20 changed files with 616 additions and 318 deletions.
2 changes: 2 additions & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ exclude_paths:
- roles/reproducer/files/cifmw-bootstrap.yml # invalid due to calls to "lookup('file')"
- roles/kustomize_deploy/molecule/flexible_loop/files/networking-environment-definition.yml # Generated
- roles/kustomize_deploy/molecule/flexible_loop/prepare.yml # import_playbook
- roles/ci_multus/molecule/local/side_effect.yml # syntax-check[empty-playbook] https://github.com/ansible/molecule/issues/3617
- roles/ci_multus/molecule/default/side_effect.yml # syntax-check[empty-playbook] https://github.com/ansible/molecule/issues/3617
strict: true
quiet: false
verbosity: 1
Expand Down
1 change: 1 addition & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MD013: false
105 changes: 57 additions & 48 deletions roles/ci_multus/README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,89 @@
# 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_namespace`: (String) The namespace where OCP resources will be installed. Defaults to `openstack`.
* `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_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 `[]`.
* `cifmw_ci_multus_dryrun`: (Bool) When enabled, tasks that require an OCP environment are skipped. Defaults to `false`.
* `cifmw_ci_multus_allow_list`: (List) Adding network names to this list allows you to define what networks will be rendered into the NAD manifest. Defaults to `[]`.
* `cifmw_ci_multus_deny_list`: (List) Adding network names to this list allows you to define what networks should be skipped from being rendered into the NAD manifest. Defaults to `[]`.

By default the `ci_multus` role reads the `cifmw_networking_env_definition` variable to generate NetworkAttachmentDefinition manifests for networks who have the Multus tool defined.

## NAD configuration layout
The user can provide a list of NAD configuration as follow:
In addition to that, you can also pass any number of "patch" variables using `cifmw_ci_multus_net_info_patch` that allow you to extend the config used to render the NetworkAttachmentDefinition manifests.
For a working example, please see `cifmw_ci_multus_net_info_patch_1` in molecule/local/molecule.yml

## cifmw_ci_multus_net_info_patch example

```YAML
cifmw_ci_multus_nad_list:
- name: storage
iface: enps6s0.21
type: macvlan
ipam:
type: whereabouts
range: 172.18.0.0/24
range_start: 172.18.0.30
range_end: 172.18.0.70
- name: bgpnet1
iface: bgpiface
type: interface
ipam:
type: whereabouts
range: 100.65.4.0/30
range_start: 100.65.4.1
range_end: 100.65.4.2
cifmw_ci_multus_net_info_patch_1:
patchnetwork:
gw_v4: 192.168.122.1
network_name: patchnetwork
network_v4: 192.168.122.0/24
interface_name: eth2
tools:
multus:
ipv4_ranges:
- start: 192.168.122.30
end: 192.168.122.70
```
`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 - Default use case consuming cifmw_networking_env_definition

```YAML
- name: Configure additional networks using multus
vars:
cifmw_ci_multus_nad_list:
- name: storage
iface: enps6s0.21
type: macvlan
ipam:
type: whereabouts
range: 172.18.0.0/24
range_start: 172.18.0.30
range_end: 172.18.0.70
ansible.builtin.include_role:
name: "ci_multus"
```
### 2 - Content from `cifmw_network_layout`:

### 2 - Using patch:

```YAML
- name: Configure additional networks using multus
vars:
cifmw_network_layout:
networks:
default:
iface: enps6s0
mtu: 1500
range: 192.168.122.0/24
cifmw_ci_multus_net_info_patch_1:
patchnetwork:
gw_v4: 192.168.122.1
network_name: patchnetwork
network_v4: 192.168.122.0/24
interface_name: eth2
tools:
multus:
range: 192.168.122.30-192.168.122.70
ipv4_ranges:
- start: 192.168.122.30
end: 192.168.122.70
ansible.builtin.include_role:
name: "ci_multus"
```

### 2 - Using allow and deny list:

```YAML
- name: Configure additional networks using multus
vars:
cifmw_ci_multus_allow_list:
- default
- awesomenet
- maybenet
cifmw_ci_multus_deny_list:
- maybenet
ansible.builtin.include_role:
name: "ci_multus"
```
7 changes: 4 additions & 3 deletions roles/ci_multus/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@

cifmw_ci_multus_basedir: "{{ cifmw_basedir | default(ansible_user_dir ~ '/ci-framework-data') }}"
cifmw_ci_multus_manifests_dir: "{{ cifmw_manifests | default(cifmw_ci_multus_basedir ~ '/artifacts/manifests') }}/ci_multus"
cifmw_ci_multus_namespace: "ci-multus"
cifmw_ci_multus_namespace: "openstack"
cifmw_ci_multus_ocp_hostname: "crc"
cifmw_ci_multus_cniversion: "0.3.1"
cifmw_ci_multus_default_nad_type: "macvlan"
cifmw_ci_multus_default_nad_ipam_type: "whereabouts"
# Input configuration for ci_multus role
cifmw_ci_multus_nad_list: []
cifmw_ci_multus_nad_extra_list: []
cifmw_ci_multus_dryrun: false
cifmw_ci_multus_allow_list: []
cifmw_ci_multus_deny_list: []
171 changes: 13 additions & 158 deletions roles/ci_multus/molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,9 @@
# License for the specific language governing permissions and limitations
# under the License.


- name: Converge
hosts: all
gather_facts: true
vars:
cifmw_path: "{{ ansible_user_dir }}/.crc/bin:{{ ansible_user_dir }}/.crc/bin/oc:{{ ansible_user_dir }}/bin:{{ ansible_env.PATH }}"
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
Expand All @@ -41,161 +36,21 @@
delegate_to: crc
delegate_facts: true

- name: Prepare the network var for the role
- name: Load shared variables
ansible.builtin.include_vars:
file: ../resources/vars/shared_vars.yml

- name: Override interface name in cifmw_networking_env_definition
vars:
_cifmw_networking_env_definition_patch:
instances:
crc:
networks:
default:
interface_name: "{{ hostvars.crc.ansible_default_ipv4.interface }}"
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
cifmw_networking_env_definition: "{{ cifmw_networking_env_definition | combine(_cifmw_networking_env_definition_patch, recursive=True) }}"

- 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 }}"

- 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"
33 changes: 31 additions & 2 deletions roles/ci_multus/molecule/default/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,34 @@ log: true
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
playbooks:
side_effect: side_effect.yml
inventory:
host_vars:
instance:
cifmw_ci_multus_net_info_patch_1:
patchnetwork:
gw_v4: 192.168.122.1
network_name: patchnetwork
network_v4: 192.168.122.0/24
interface_name: eth2
tools:
multus:
ipv4_ranges:
- start: 192.168.122.30
end: 192.168.122.70

cifmw_path: "{{ ansible_user_dir }}/.crc/bin:{{ ansible_user_dir }}/.crc/bin/oc:{{ ansible_user_dir }}/bin:{{ ansible_env.PATH }}"
cifmw_openshift_kubeconfig: "{{ ansible_user_dir }}/.crc/machines/crc/kubeconfig"
testpod_name: "pod-testnad"
prerun: false
scenario:
test_sequence:
- destroy
- create
- converge
- verify ../resources/verify.yml
- verify verify_crc.yml
- side_effect ../resources/clean.yml
- verify ../resources/verify_clean.yml
- verify verify_clean_crc.yml
Empty file.
Loading

0 comments on commit e9e1037

Please sign in to comment.