Skip to content

Commit a0521d8

Browse files
authored
Project refactor (#125)
* Project refactor Assisted-by: Cursor * Fix issue with CRD spec - additionalProperties and properties are mutual exclusive. Refactor some other code
1 parent b54f954 commit a0521d8

File tree

52 files changed

+887
-341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+887
-341
lines changed

grout-operator/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased] -
66

7+
## [0.2.2] - 2025-08-13
8+
9+
- No functional changes to operator logic.
10+
- Documentation improvements for CRD specification, Grout Ansible role and deployment details.
11+
712
## [0.2.1] - 2025-08-05
813

914
- Updated OperatorSDK to v1.41.1

grout-operator/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ FROM quay.io/operator-framework/ansible-operator:v1.39.0
33
LABEL name="NFV Example CNF Application Operator" \
44
maintainer="telcoci" \
55
vendor="fredco" \
6-
version="v0.2.1" \
7-
release="v0.2.1" \
6+
version="v0.2.2" \
7+
release="v0.2.2" \
88
summary="An example CNF for platform validation" \
99
description="An example CNF for platform validation"
1010

grout-operator/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# To re-generate a bundle for another specific version without changing the standard setup, you can:
44
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
55
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
6-
VERSION := 0.2.1
6+
VERSION := 0.2.2
77

88
# Set the Operator SDK version to use. By default, what is installed on the system is used.
99
# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.

grout-operator/config/crd/bases/examplecnf.openshift.io_grouts.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,54 @@ spec:
3232
spec:
3333
description: Spec defines the desired state of Grout
3434
type: object
35+
properties:
36+
privileged:
37+
description: Run the container in privileged mode
38+
type: boolean
39+
imagePullPolicy:
40+
description: Image pull policy for the Grout container
41+
type: string
42+
enum:
43+
- Always
44+
- IfNotPresent
45+
- Never
46+
size:
47+
description: Number of replicas for the Grout deployment
48+
type: integer
49+
minimum: 1
50+
networks:
51+
description: List of NetworkAttachmentDefinitions to attach to the pod
52+
type: array
53+
items:
54+
type: object
55+
properties:
56+
name:
57+
description: NetworkAttachmentDefinition name (namespace/name or name)
58+
type: string
59+
count:
60+
description: Number of interfaces to request from this network
61+
type: integer
62+
minimum: 1
63+
default: 1
64+
mac:
65+
description: Optional list of MAC addresses, one per interface
66+
type: array
67+
items:
68+
type: string
69+
ip:
70+
description: Optional list of IP addresses, one per interface
71+
type: array
72+
items:
73+
type: string
74+
runDeployment:
75+
description: Whether to run the deployment automation (0 to disable, 1 to enable)
76+
type: integer
77+
enum:
78+
- 0
79+
- 1
80+
runtime_class_name:
81+
description: Optional RuntimeClass to use for the pod
82+
type: string
3583
x-kubernetes-preserve-unknown-fields: true
3684
status:
3785
description: Status defines the observed state of Grout

grout-operator/molecule/default/tasks/grout_test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
- name: Create the examplecnf.openshift.io/v1.Grout
3-
k8s:
3+
kubernetes.core.k8s:
44
state: present
55
namespace: '{{ namespace }}'
66
definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}"
@@ -13,6 +13,6 @@
1313
cr_file: 'examplecnf_v1_grout.yaml'
1414

1515
- name: Add assertions here
16-
assert:
16+
ansible.builtin.assert:
1717
that: false
1818
fail_msg: FIXME Add real assertions for your operator
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Grout Ansible Role
2+
3+
This Ansible role (`grout`) is designed to deploy and manage the Grout application in a Kubernetes/OpenShift environment. It automates the creation of necessary Kubernetes resources, parses network definitions, and configures the Grout deployment according to user-specified parameters.
4+
5+
## Default Variables
6+
7+
The following variables are defined in [`defaults/main.yml`](defaults/main.yml):
8+
9+
| Variable | Default Value | Description |
10+
|-----------------------|------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
11+
| `image_grout` | quay.io/rh-nfv-int/grout-container-app-cnfapp@sha256:112bed772707280de16a64eb4fb3c3c0ec027fa030372dff05927d105bc822fd | Container image for the Grout application. |
12+
| `size` | 1 | Number of replicas for the Grout deployment. |
13+
| `skip_annot` | false | Whether to skip annotation steps. |
14+
| `networks` | [] | List of network definitions (see below for structure). |
15+
| `image_pull_policy` | IfNotPresent | Image pull policy for the Grout container (`Always`, `IfNotPresent`, or `Never`). |
16+
| `privileged` | false | Whether to run the container in privileged mode. |
17+
| `hugepage_1gb_count` | 4Gi | Amount of 1Gi hugepages to allocate. |
18+
| `memory` | 1000Mi | Memory request for the Grout container. |
19+
| `cpu` | 4 | CPU request for the Grout container. |
20+
| `network_resources` | {} | Internal variable for tracking network resource usage. |
21+
| `resources` | [] | List of additional resources to be used. |
22+
| `environments` | {} | Environment variables to set in the container. |
23+
| `rx_queues` | 2 | Number of RX queues. |
24+
25+
### Example `networks` Variable Structure
26+
27+
The `networks` variable is a list of dictionaries, each describing a network attachment. Example:
28+
29+
```
30+
"networks": [
31+
{
32+
"count": 1,
33+
"ip": [
34+
"192.168.36.60/26"
35+
],
36+
"mac": [
37+
"80:03:0f:f1:89:01"
38+
],
39+
"name": "example-cnf-net1"
40+
},
41+
{
42+
"count": 1,
43+
"ip": [
44+
"192.168.36.100/26"
45+
],
46+
"mac": [
47+
"80:03:0f:f1:89:02"
48+
],
49+
"name": "example-cnf-net2"
50+
}
51+
]
52+
```
53+
54+
## How the Ansible Tasks Work
55+
56+
The Grout role uses a series of Ansible tasks (see [`tasks/main.yml`](tasks/main.yml)) to automate the deployment and configuration of the Grout application. Here is an overview of the main steps:
57+
58+
1. **Initialization**:
59+
The role initializes internal variables such as `network_resources` (to track network resource usage) and `network_name_list` (to keep a list of network names).
60+
61+
2. **Input Validation**:
62+
The role checks that at least one of the `networks` or `resources` variables is provided. If both are empty, the playbook fails with an error.
63+
64+
3. **Network Parsing**:
65+
If the `networks` variable is defined and not empty, the role loops through each network entry and includes the `network-parse.yaml` task file. This subtask:
66+
- Extracts the network name and details.
67+
- Looks up the corresponding `NetworkAttachmentDefinition` in the cluster.
68+
- Gathers resource names, counts, and updates the `network_resources` dictionary accordingly.
69+
- Handles duplicate resources by incrementing their counts.
70+
- Collects a list of all network names used.
71+
72+
4. **Resource Parsing**:
73+
If `resources` are defined and `networks` is empty, the role populates `network_resources` directly from the `resources` list.
74+
75+
5. **Debugging and Output**:
76+
Throughout the process, the role prints debug information for variables like `networks`, `resources`, `network_resources`, and `network_name_list` to aid troubleshooting.
77+
78+
6. **Kubernetes Resource Creation**:
79+
The role then creates the necessary Kubernetes resources for the Grout application:
80+
- **ServiceAccount**: For the Grout pod to interact with the cluster.
81+
- **Role and RoleBinding**: To grant the required permissions.
82+
- **Deployment**: To launch the Grout application pods using the specified configuration.
83+
- **PodDisruptionBudget**: To ensure high availability during node maintenance or upgrades.
84+
85+
These tasks ensure that the Grout application is deployed with the correct network attachments, resource allocations, and permissions, based on the variables you provide to the role.
86+
87+
## Deployment Details
88+
89+
The Grout role creates a Kubernetes `Deployment` resource to manage the lifecycle of the Grout application pods. This deployment is defined using a Jinja2 template (`deployment.yml`) and is rendered with the variables you provide to the role. The deployment includes the following key features:
90+
91+
- **Replica Count**: The number of pod replicas is controlled by the `size` variable.
92+
- **Container Image**: The Grout container image is specified by the `image_grout` variable, with the pull policy set by `image_pull_policy`.
93+
- **Network Attachments**: The deployment attaches the specified networks to the pods using the `networks` variable, enabling SR-IOV or other CNI-based networking as required.
94+
- **Resource Requests and Limits**: CPU, memory, and hugepage resources are set according to the role defaults or your overrides.
95+
- **Security Context**: The pod can be run in privileged mode if `privileged` is set to `true`.
96+
- **RuntimeClass**: If a high-performance runtime is specified (via `runtime_class_name`), it is set on the pod for advanced scheduling or isolation.
97+
- **Environment Variables**: Any custom environment variables can be injected using the `environments` variable.
98+
- **Service Account**: The deployment uses a dedicated ServiceAccount created by the role to ensure proper permissions.
99+
- **PodDisruptionBudget**: A PodDisruptionBudget is also created to help maintain pod availability during node drains or upgrades.
100+
101+
This deployment ensures that the Grout application is robustly managed by Kubernetes, with flexible configuration for networking, resources, and security to suit a variety of CNF (Cloud-Native Network Function) scenarios.

grout-operator/roles/grout/defaults/main.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,32 @@
44
# https://github.com/openshift-kni/example-cnf/blob/main/grout-operator/Makefile - See "ensure_digests" task
55
image_grout: "quay.io/rh-nfv-int/grout-container-app-cnfapp@sha256:112bed772707280de16a64eb4fb3c3c0ec027fa030372dff05927d105bc822fd" # v0.2.0
66

7+
# Number of replicas for the Grout deployment.
78
size: 1
9+
# Whether to skip annotation steps.
810
skip_annot: false
911

1012
# PCI devices to be used during execution should be obtained from these networks
1113
# Grout application entrypoint script should get PCI and then run Grout execution
1214
networks: []
1315

16+
# Image pull policy for the Grout container (Always, IfNotPresent, or Never).
1417
image_pull_policy: IfNotPresent
18+
# Whether to run the container in privileged mode.
1519
privileged: false
20+
# Amount of 1Gi hugepages to allocate.
1621
hugepage_1gb_count: 4Gi
22+
# Memory request for the Grout container.
1723
memory: 1000Mi
24+
# CPU request for the Grout container.
1825
cpu: 4
1926

27+
# Internal variable for tracking network resource usage.
2028
network_resources: {}
29+
# List of additional resources to be used.
2130
resources: []
22-
ethpeer_maclist: []
31+
# Environment variables to set in the container.
2332
environments: {}
2433

34+
# Number of RX queues.
2535
rx_queues: 2

grout-operator/roles/grout/tasks/main.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
---
22
# tasks file for Grout
3-
- set_fact:
3+
- ansible.builtin.set_fact:
44
network_resources: {}
55
network_name_list: []
66

77
- name: print network list
8-
debug:
8+
ansible.builtin.debug:
99
var: networks
1010

1111
- name: print resource list
12-
debug:
12+
ansible.builtin.debug:
1313
var: resources
1414

1515
- name: Check if networks parameter is empty
16-
fail:
16+
ansible.builtin.fail:
1717
msg: "networks or resources parameter is required"
1818
when:
1919
- networks|length == 0
2020
- resources|length == 0
2121

2222
- name: "Parse network"
23-
include_tasks: network-parse.yaml
23+
ansible.builtin.include_tasks: network-parse.yaml
2424
when: networks|default([])|length > 0
2525
loop: "{{ networks }}"
2626
loop_control:
2727
loop_var: network_item
2828

2929
- name: print network_resources after parsing networks
30-
debug:
30+
ansible.builtin.debug:
3131
var: network_resources
3232

3333
- name: print network_name_list after parsing networks
34-
debug:
34+
ansible.builtin.debug:
3535
var: network_name_list
3636

3737
- name: "Parse resources if defined and when sriov network is not defined"
38-
set_fact:
38+
ansible.builtin.set_fact:
3939
network_resources: "{{ network_resources | combine({item.name: item.count}) }}"
4040
loop: "{{ resources }}"
4141
when:
4242
- networks|default([])|length == 0
4343
- resources|default([])|length > 0
4444

4545
- name: print network resources map
46-
debug:
46+
ansible.builtin.debug:
4747
var: network_resources
4848

4949
- name: Create ServiceAccount for Grout resource
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
---
2-
- debug:
2+
- ansible.builtin.debug:
33
msg: "Gather network info of network: {{ network_item.name }}"
44

55
- name: Initialize variable that checks if resource name is already on the dict
6-
set_fact:
6+
ansible.builtin.set_fact:
77
resource_exists: false
88

9-
- set_fact:
9+
- ansible.builtin.set_fact:
1010
net: "{{ network_item.name.split('/')[1] }}"
1111
when: "'/' in network_item.name"
1212

13-
- set_fact:
13+
- ansible.builtin.set_fact:
1414
net: "{{ network_item.name }}"
1515
when: "'/' not in network_item.name"
1616

1717
- name: print net
18-
debug:
18+
ansible.builtin.debug:
1919
var: net
2020

21-
- set_fact:
21+
- ansible.builtin.set_fact:
2222
net_def: "{{ lookup('k8s', kind='NetworkAttachmentDefinition', namespace=ansible_operator_meta.namespace, resource_name=net) }}"
2323
failed_when: net_def|length == 0
2424

2525
- name: print net_def
26-
debug:
26+
ansible.builtin.debug:
2727
var: net_def
2828

29-
- set_fact:
29+
- ansible.builtin.set_fact:
3030
network_port_count: "{{ network_item.count|default(1) }}"
3131

3232
- name: print network_port_count
33-
debug:
33+
ansible.builtin.debug:
3434
var: network_port_count
3535

36-
- set_fact:
36+
- ansible.builtin.set_fact:
3737
network_resource_name: "{{ net_def['metadata']['annotations']['k8s.v1.cni.cncf.io/resourceName'] }}"
3838

3939
- name: print network_resource_name
40-
debug:
40+
ansible.builtin.debug:
4141
var: network_resource_name
4242

4343
- name: Update resource_exists if the resource is in the dict
44-
set_fact:
44+
ansible.builtin.set_fact:
4545
resource_exists: true
4646
with_dict: "{{ network_resources }}"
4747
when: "network_resource_name in item.key"
4848

4949
- name: print resource_exists
50-
debug:
50+
ansible.builtin.debug:
5151
var: resource_exists
5252

5353
- name: Include new network resource if it was not included before
54-
set_fact:
54+
ansible.builtin.set_fact:
5555
network_resources: "{{ network_resources | combine( {network_resource_name : network_port_count} ) }}"
5656
when: not resource_exists
5757

5858
- name: Update network resource
5959
block:
6060
- name: Update count for network resource
61-
set_fact:
61+
ansible.builtin.set_fact:
6262
network_resources: "{{ network_resources | combine(new_item, recursive=true) }}"
6363
vars:
6464
new_item: "{ '{{ item.key }}': {{ item.value|int + network_port_count|int }} }"
@@ -67,12 +67,12 @@
6767
when: resource_exists
6868

6969
- name: print network_resources
70-
debug:
70+
ansible.builtin.debug:
7171
var: network_resources
7272

73-
- set_fact:
73+
- ansible.builtin.set_fact:
7474
network_name_list: "{{ network_name_list + [net] }}"
7575

7676
- name: print network_name_list
77-
debug:
77+
ansible.builtin.debug:
7878
var: network_name_list

0 commit comments

Comments
 (0)