diff --git a/playbooks/deploy-ocp-operators.yaml b/playbooks/deploy-ocp-operators.yaml new file mode 100644 index 0000000..f54d703 --- /dev/null +++ b/playbooks/deploy-ocp-operators.yaml @@ -0,0 +1,82 @@ +# This playbook is not officially supported and comes with no guarantees. +# Use it at your own risk. Ensure you test thoroughly in your environment +# before deploying to production. + +## Overview: +# This Ansible playbook automates the deployment of multiple OpenShift operators using +# the **Operator Lifecycle Manager (OLM)**. It includes tasks to install necessary dependencies, +# configure variables, and deploy the specified operators into the designated namespaces. + +## Prerequisites: +# - Ansible 2.9+ installed on the control node. +# - Ansible control node configured with necessary permissions. +# - SSH Access to bastion hosts. +# - ocp version of link to operator release version +# - pre-configured hosts_vars and grup_vars directories +# - installed openshift cluster +# - KUBECONFIG file + +## Roles Requirements +# The playbook uses role: +# - redhatci.ocp.catalog_source +# - redhatci.ocp.catalog_source + +## Usage: +# - Ensure all required variables are defined in the inventory or host_vars/group_vars. +# - Execute the playbook using Ansible's command-line tool: +# +# ansible-playbook ./playbooks/deploy-cnf-operators.yaml -i ./inventories/ocp-deployment/deploy-ocp-hybrid-multinode.yml \ +# --extra-vars 'kubeconfig="/path/to/kubeconfig" \ +# version="4.16" operators=[{"name":"sriov-network-operator","catalog":"redhat-operators-stage","nsname":"openshift-sriov-network-operator"},\ +# {"name":"metallb-operator","catalog":"redhat-operators-stage","nsname":"metallb-system","channel":"stable","og_spec":{}}] +# +# Notes: +# - This playbook assumes the OCP cluster and bastion hosts are pre-installed and ready. +# - Test in a non-production environment before deploying. +--- +- name: Deploy operator + hosts: bastion + gather_facts: false + # Refer to the variables below as an example. + # vars: + # version: "4.17" + # operators: # Refer as example + # - name: sriov-network-operator + # catalog: redhat-operators-stage + # nsname: openshift-sriov-network-operator + # - name: ptp-operator + # catalog: redhat-operators-stage + # nsname: openshift-ptp + # ns_labels: + # workload.openshift.io/allowed: management + # name: openshift-ptp + # - name: kubernetes-nmstate-operator + # catalog: redhat-operators + # nsname: openshift-nmstate + # - name: sriov-fec + # catalog: certified-operators + # nsname: vran-acceleration-operators + # channel: stable + # - name: metallb-operator + # catalog: redhat-operators-stage + # nsname: metallb-system + # channel: stable + # og_spec: {} + environment: + K8S_AUTH_KUBECONFIG: "{{ kubeconfig }}" + tasks: + - name: Install requirements + ansible.builtin.pip: + name: + - kubernetes + - openshift + state: present + + - name: Install Operators + ansible.builtin.include_role: + name: ocp_operator_deployment + vars: + ocp_operator_deployment_version: "{{ version }}" + ocp_operator_deployment_operators: "{{ operators | from_json }}" + ocp_operator_deployment_stage_repo_image: "{{ stage_catalog_index_image | default(omit) }}" + ocp_operator_deployment_stage_cs_secret: "{{ registry_credentials | default(omit) }}" diff --git a/playbooks/roles/ocp_operator_deployment/README.md b/playbooks/roles/ocp_operator_deployment/README.md new file mode 100644 index 0000000..a407e36 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/README.md @@ -0,0 +1,111 @@ +# OCP Operator Deployment Ansible Role + +## Disclaimer +This role is provided as-is, without any guarantees of support or maintenance. +The author or contributors are not responsible for any issues arising from the use of this role. Use it at your own discretion. + +## Overview +The `ocp_operator_deployment` Ansible role automates the deployment of OpenShift operators using the **Operator Lifecycle Manager (OLM)**. It supports different catalog sources, including **stage, pre-ga, and brew** repositories. + +## Features +- Ensures required variables are defined before execution. +- Deploys operators from different catalog sources (`stage`, `pre-ga`, `brew`). +- Creates **CatalogSource** and required **secrets** dynamically. +- Installs and configures operators using OLM. +- Supports custom **OperatorGroup** configurations. +- Applies default operator configurations if available. + +## Requirements +- Ansible **2.9+** +- OpenShift Cluster **4.x** +- redhatci.ocp.catalog_source +- redhatci.ocp.catalog_source +- [`kubernetes.core` collection](https://docs.ansible.com/ansible/latest/collections/kubernetes/core/index.html) installed: + ```sh + ansible-galaxy collection install kubernetes.core + +## Role Variables + +### Required Variables + +- **`ocp_operator_deployment_operators`** – List of operators to deploy. +- **`ocp_operator_deployment_version`** – Version of the deployment. + +### Optional Variables + +- **`ocp_operator_deployment_catalog_source_ns`** (default: `"openshift-marketplace"`) + Namespace for the CatalogSource. + +- **`ocp_operator_deployment_stage_repo_image`** + Image for the stage CatalogSource (**required if using `stage` catalog**). + +- **`ocp_operator_deployment_stage_cs_secret`** + Secret for accessing the stage registry (**required if using `stage` catalog**). + +- **`ocp_operator_deployment_default_label`** (default: `{}`) + Default labels for operator namespaces. + +## Operator List Example + +Each operator should be defined with the required parameters: + +```yaml +ocp_operator_deployment_operators: + - name: "example-operator" + namespace: "example-namespace" + catalog: "stage" + channel: "stable" # optional + og_spec: # optional + targetNamespaces: + - "example-namespace" + starting_csv: "example-operator.v1.2.3" # optional + +## Usage + +### Basic Playbook Example - deploy from prod + +```yaml +- name: Deploy OpenShift Operators + hosts: localhost + roles: + - role: ocp_operator_deployment + vars: + ocp_operator_deployment_version: "4.16" + ocp_operator_deployment_operators: + - name: "example-operator" + namespace: "example-namespace" + catalog: "stage" + channel: "stable" +``` + +## Tasks Breakdown + +1. **Verify Required Variables** + - Ensures all required inputs are provided before execution. + +2. **Deploy CatalogSources** + - Creates the necessary **CatalogSource** in OpenShift. + - Generates required **secrets** for the registry. + +3. **Deploy Operators** + - Uses **OLM** to deploy specified operators. + - Supports different installation **channels**. + +4. **Apply Configurations** + - Automatically applies **default operator configurations** (if available). + +## Dependencies + +This role does not have any hard dependencies but requires the [`kubernetes.core`](https://docs.ansible.com/ansible/latest/collections/kubernetes/core/index.html) collection. + +## License + +Apache + +## Authors + +- **Nikita Kononov** + +## Contributions + +Feel free to **open issues** or **submit PRs** to enhance functionality! diff --git a/playbooks/roles/ocp_operator_deployment/defaults/main.yml b/playbooks/roles/ocp_operator_deployment/defaults/main.yml new file mode 100644 index 0000000..53f984f --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# defaults file for ocp_operator_deployment +ocp_operator_deployment_default_label: + workload.openshift.io/allowed: management +ocp_operator_deployment_catalog_source_ns: openshift-marketplace diff --git a/playbooks/roles/ocp_operator_deployment/meta/main.yml b/playbooks/roles/ocp_operator_deployment/meta/main.yml new file mode 100644 index 0000000..a26ad92 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/meta/main.yml @@ -0,0 +1,13 @@ +galaxy_info: + author: Nikita Kononov + description: Ansible role for deploying OpenShift operators using OLM from different catalog sources. + company: Red Hat + license: Apache-2.0 + min_ansible_version: "2.9" + galaxy_tags: + - openshift + - kubernetes + - operator + - olm + - deployment +dependencies: [] diff --git a/playbooks/roles/ocp_operator_deployment/tasks/deploy_brew.yaml b/playbooks/roles/ocp_operator_deployment/tasks/deploy_brew.yaml new file mode 100644 index 0000000..04791ee --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/tasks/deploy_brew.yaml @@ -0,0 +1,3 @@ +- name: Todo - Brew + ansible.builtin.fail: + msg: TODO - implement task list diff --git a/playbooks/roles/ocp_operator_deployment/tasks/deploy_operator.yaml b/playbooks/roles/ocp_operator_deployment/tasks/deploy_operator.yaml new file mode 100644 index 0000000..9448ac4 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/tasks/deploy_operator.yaml @@ -0,0 +1,32 @@ +--- +- name: Set OperatorGroup spec configuration + ansible.builtin.set_fact: + operator_group_spec_config: >- + {{ + item.og_spec if item.og_spec is defined else + {'targetNamespaces': [item.nsname]} + }} + +- name: Deploy operator via olm + ansible.builtin.include_role: + name: redhatci.ocp.olm_operator + vars: + operator: "{{ item.name }}" + source: "{{ item.catalog }}" + namespace: "{{ item.nsname }}" + operator_group_name: "{{ item.og_name | default(item.name) }}" + channel: "{{ item.channel | default(omit) }}" + ns_labels: + "{{ item.ns_labels | default(ocp_operator_deployment_default_label) }}" + operator_group_spec: "{{ operator_group_spec_config }}" + starting_csv: "{{ item.starting_csv | default(omit) }}" + install_approval: "{{ item.install_approval | default('Automatic') }}" + kubeconfig: /home/telcov10n/project/generated/kni-qe-92/auth/kubeconfig + +- name: Apply default operator configuration if exist + kubernetes.core.k8s: + template: "{{ role_path }}/templates/{{ item.name }}-config.j2" + state: present + force: true + register: result + ignore_errors: true diff --git a/playbooks/roles/ocp_operator_deployment/tasks/deploy_pre_ga.yaml b/playbooks/roles/ocp_operator_deployment/tasks/deploy_pre_ga.yaml new file mode 100644 index 0000000..4340ab3 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/tasks/deploy_pre_ga.yaml @@ -0,0 +1,3 @@ +- name: Todo - Pre-Ga + ansible.builtin.fail: + msg: TODO - implement task list diff --git a/playbooks/roles/ocp_operator_deployment/tasks/deploy_stage.yaml b/playbooks/roles/ocp_operator_deployment/tasks/deploy_stage.yaml new file mode 100644 index 0000000..672519b --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/tasks/deploy_stage.yaml @@ -0,0 +1,46 @@ +- name: Verify if stage catalog already deployed + kubernetes.core.k8s_info: + api: operators.coreos.com/v1alpha1 + namespace: "{{ ocp_operator_deployment_catalog_source_ns }}" + kind: CatalogSource + name: "{{ item.catalog }}" + register: catalog_source + +- name: Check if secret exists + kubernetes.core.k8s_info: + api_version: v1 + kind: Secret + namespace: "{{ ocp_operator_deployment_catalog_source_ns }}" + name: "{{ item.catalog }}" + register: secret_check + +- name: Create catalog source secret if missing + when: secret_check.resources | length == 0 + vars: + _secret_definition: |- + apiVersion: v1 + kind: Secret + type: kubernetes.io/dockerconfigjson + metadata: + name: "{{ item.catalog }}" + namespace: "{{ ocp_operator_deployment_catalog_source_ns }}" + data: + .dockerconfigjson: "{{ ocp_operator_deployment_stage_cs_secret | to_json | b64encode }}" + kubernetes.core.k8s: + definition: "{{ _secret_definition }}" + state: present + +- name: Deploy catalog source if not present + when: catalog_source.resources | length == 0 + ansible.builtin.include_role: + name: redhatci.ocp.catalog_source + vars: + cs_name: "{{ item.catalog }}" + cs_namespace: "{{ ocp_operator_deployment_catalog_source_ns }}" + cs_image: "{{ ocp_operator_deployment_stage_repo_image }}:v{{ ocp_operator_deployment_version }}" + cs_publisher: "Red Hat" + cs_secrets: + - "{{ item.catalog }}" + cs_update_strategy: + registryPoll: + interval: 15m diff --git a/playbooks/roles/ocp_operator_deployment/tasks/main.yml b/playbooks/roles/ocp_operator_deployment/tasks/main.yml new file mode 100644 index 0000000..137d583 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/tasks/main.yml @@ -0,0 +1,37 @@ +--- +# tasks file for ocp_operator_deployment +- name: Verify that required variables are present + ansible.builtin.assert: + that: + - ocp_operator_deployment_operators is defined + - ocp_operator_deployment_operators | length > 0 + - ocp_operator_deployment_version is defined + fail_msg: Required variables are not set or empty + +- name: Verify that stage repo required variables are present + loop: "{{ ocp_operator_deployment_operators }}" + when: item.catalog == stage + ansible.builtin.assert: + that: + - ocp_operator_deployment_stage_repo_image is defined + - ocp_operator_deployment_stage_cs_secret is defined + fail_msg: Required stage variables are not set + +- name: Deploy stage CatalogSource + ansible.builtin.include_tasks: deploy_stage.yaml + loop: "{{ ocp_operator_deployment_operators }}" + when: item.catalog == stage + +- name: Deploy pre-ga CatalogSource + ansible.builtin.include_tasks: deploy_pre_ga.yaml + loop: "{{ ocp_operator_deployment_operators }}" + when: item.catalog == pre_ga + +- name: Deploy brew CatalogSource + ansible.builtin.include_tasks: deploy_brew.yaml + loop: "{{ ocp_operator_deployment_operators }}" + when: item.catalog == brew + +- name: "Deploy operator" + ansible.builtin.include_tasks: deploy_operator.yaml + loop: "{{ ocp_operator_deployment_operators }}" diff --git a/playbooks/roles/ocp_operator_deployment/templates/kubernetes-nmstate-operator-config.j2 b/playbooks/roles/ocp_operator_deployment/templates/kubernetes-nmstate-operator-config.j2 new file mode 100644 index 0000000..cbba0c6 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/templates/kubernetes-nmstate-operator-config.j2 @@ -0,0 +1,4 @@ +apiVersion: nmstate.io/v1 +kind: NMState +metadata: + name: nmstate diff --git a/playbooks/roles/ocp_operator_deployment/templates/metallb-operator-config.j2 b/playbooks/roles/ocp_operator_deployment/templates/metallb-operator-config.j2 new file mode 100644 index 0000000..16da825 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/templates/metallb-operator-config.j2 @@ -0,0 +1,5 @@ +apiVersion: metallb.io/v1beta1 +kind: MetalLB +metadata: + name: metallb + namespace: "{{ item.nsname }}" diff --git a/playbooks/roles/ocp_operator_deployment/templates/sriov-network-operator-config.j2 b/playbooks/roles/ocp_operator_deployment/templates/sriov-network-operator-config.j2 new file mode 100644 index 0000000..900a498 --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/templates/sriov-network-operator-config.j2 @@ -0,0 +1,10 @@ +apiVersion: sriovnetwork.openshift.io/v1 +kind: SriovOperatorConfig +metadata: + name: default + namespace: "{{ item.nsname }}" +spec: + enableInjector: true + enableOperatorWebhook: true + logLevel: 2 + disableDrain: false diff --git a/playbooks/roles/ocp_operator_deployment/vars/main.yml b/playbooks/roles/ocp_operator_deployment/vars/main.yml new file mode 100644 index 0000000..329800a --- /dev/null +++ b/playbooks/roles/ocp_operator_deployment/vars/main.yml @@ -0,0 +1,6 @@ +--- +# vars file for ocp_operator_deployment +stage: redhat-operators-stage +prod: redhat-operators +pre_ga: redhat-operators-pre-ga +brew: redhat-operators-brew diff --git a/requirements.yml b/requirements.yml index aef3634..e32f072 100644 --- a/requirements.yml +++ b/requirements.yml @@ -4,3 +4,5 @@ collections: version: "1.3.0" - name: redhatci.ocp version: "2.0.1740507199" + - name: kubernetes.core + version: "2.4.2"