|
@@ -0,0 +1,221 @@
|
|
|
|
+---
|
|
|
|
+# Ensures all the operator artifacts are created and waits for CSV to succeed.
|
|
|
|
+#
|
|
|
|
+# The following variables must exist:
|
|
|
|
+#
|
|
|
|
+# op:
|
|
|
|
+# desired_csv
|
|
|
|
+# op_nsp
|
|
|
|
+# op_cat
|
|
|
|
+# op_pkg
|
|
|
|
+# op_chn
|
|
|
|
+# op_mod
|
|
|
|
+#
|
|
|
|
+# NOTE: Do NOT test by checking for presence of API resources - they do not always get cleaned up.
|
|
|
|
+
|
|
|
|
+- debug:
|
|
|
|
+ msg: Deploying operator {{ op.op_pkg }} in namespace {{ op.op_nsp }}...
|
|
|
|
+
|
|
|
|
+# See if the CSV is available already (anywhere), meaning the operator is already installed.
|
|
|
|
+- name: Check if the CSV exists already
|
|
|
|
+ k8s_info:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: operators.coreos.com/v1alpha1
|
|
|
|
+ kind: clusterserviceversion
|
|
|
|
+ register: all_csv
|
|
|
|
+
|
|
|
|
+- name: Find the wanted CSV among all CSVs
|
|
|
|
+ set_fact:
|
|
|
|
+ found_csv: '{{ (all_csv | community.general.json_query("resources[?contains(metadata.name, `" + op.op_pkg + ".`)]")) }}'
|
|
|
|
+ when:
|
|
|
|
+ - all_csv.resources is defined
|
|
|
|
+ - (all_csv.resources | length) > 0
|
|
|
|
+
|
|
|
|
+- name: Get details about the CSV if found
|
|
|
|
+ set_fact:
|
|
|
|
+ csv_ns: "{{ found_csv[0] | community.general.json_query('metadata.namespace') }}"
|
|
|
|
+ csv_name: "{{ found_csv[0] | community.general.json_query('metadata.name') }}"
|
|
|
|
+ when:
|
|
|
|
+ - found_csv is defined
|
|
|
|
+ - (found_csv | length) > 0
|
|
|
|
+
|
|
|
|
+- debug:
|
|
|
|
+ msg: Operator {{ op.op_pkg }} is already installed in {{ csv_ns }} as {{ csv_name }} (desired_csv == {{ op.desired_csv }}).
|
|
|
|
+ when:
|
|
|
|
+ - csv_ns is defined
|
|
|
|
+ - csv_name is defined
|
|
|
|
+
|
|
|
|
+- name: Only proceed here if the CSV was not found anywhere yet
|
|
|
|
+ block:
|
|
|
|
+
|
|
|
|
+ # Check if package provides desired_csv in any of the channels
|
|
|
|
+ - name: Get packagemanifest
|
|
|
|
+ k8s_info:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: packages.operators.coreos.com/v1
|
|
|
|
+ kind: packagemanifest
|
|
|
|
+ namespace: openshift-marketplace
|
|
|
|
+ name: "{{ op.op_pkg }}"
|
|
|
|
+ register: pkg_mft
|
|
|
|
+
|
|
|
|
+ - name: Search for any channels that provide desired_csv
|
|
|
|
+ set_fact:
|
|
|
|
+ found_chn: '{{ (pkg_mft | community.general.json_query("resources[0].status.channels[?currentCSV == `" + op.desired_csv + "`].name")) }}'
|
|
|
|
+ when:
|
|
|
|
+ - pkg_mft is defined
|
|
|
|
+ - pkg_mft.resources | length > 0
|
|
|
|
+
|
|
|
|
+ - name: Fail if no channel provides the desired_csv
|
|
|
|
+ fail:
|
|
|
|
+ msg: No {{ op.op_pkg }} channel provides {{ op.desired_csv }}
|
|
|
|
+ when:
|
|
|
|
+ - found_chn is defined
|
|
|
|
+ - found_chn | length == 0
|
|
|
|
+
|
|
|
|
+ - name: Fail if selected channel does not provide the desired_csv
|
|
|
|
+ fail:
|
|
|
|
+ msg: Operator {{ op.op_pkg }} selected channel {{ op.op_chn }} does not provide {{ op.desired_csv }} - {{ found_chn }}
|
|
|
|
+ when:
|
|
|
|
+ - found_chn is defined
|
|
|
|
+ - found_chn | length > 0
|
|
|
|
+ - op.op_chn not in found_chn
|
|
|
|
+
|
|
|
|
+ # Create the namespace if necessary
|
|
|
|
+ - name: Make sure the namespace is there
|
|
|
|
+ k8s:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: v1
|
|
|
|
+ kind: namespace
|
|
|
|
+ name: "{{ op.op_nsp }}"
|
|
|
|
+
|
|
|
|
+ # Check for operator group - if existing, make sure it's compatible; otherwise create it
|
|
|
|
+ - name: See if there are any OperatorGroups
|
|
|
|
+ k8s_info:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: operators.coreos.com/v1
|
|
|
|
+ kind: operatorgroup
|
|
|
|
+ namespace: "{{ op.op_nsp }}"
|
|
|
|
+ register: found_opgrp
|
|
|
|
+
|
|
|
|
+ - name: Die if more than one OG
|
|
|
|
+ ansible.builtin.fail:
|
|
|
|
+ msg: More than one OperatorGroup found in project.
|
|
|
|
+ when: (found_opgrp.resources | length) > 1
|
|
|
|
+
|
|
|
|
+ - name: Die if op_mod is not recognised
|
|
|
|
+ ansible.builtin.fail:
|
|
|
|
+ msg: Unrecognised op.op_mod ({{ op.op_mod }})
|
|
|
|
+ when: op.op_mod not in ["all", "self"]
|
|
|
|
+
|
|
|
|
+ - name: Die if op_mod does not match found OG mode
|
|
|
|
+ ansible.builtin.fail:
|
|
|
|
+ msg: Found OG mode does not match required ({{ op.op_mod }})
|
|
|
|
+ when: |
|
|
|
|
+ ((found_opgrp.resources | length) == 1 and op.op_mod == "all" and found_opgrp.resources[0].status.namespaces != [""]) or
|
|
|
|
+ ((found_opgrp.resources | length) == 1 and op.op_mod == "self" and found_opgrp.resources[0].status.namespaces != [op.op_nsp])
|
|
|
|
+
|
|
|
|
+ - name: Set fact for namespaces of OG if we require all
|
|
|
|
+ set_fact:
|
|
|
|
+ og_spec: []
|
|
|
|
+ when:
|
|
|
|
+ - op.op_mod == "all"
|
|
|
|
+ - (found_opgrp.resources | length) == 0
|
|
|
|
+
|
|
|
|
+ - name: Set fact for namespaces of OG if we require self
|
|
|
|
+ set_fact:
|
|
|
|
+ og_spec: ["{{op.op_nsp}}"]
|
|
|
|
+ when:
|
|
|
|
+ - op.op_mod == "self"
|
|
|
|
+ - (found_opgrp.resources | length) == 0
|
|
|
|
+
|
|
|
|
+ - name: Create the OperatorGroup if not there
|
|
|
|
+ k8s:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: operators.coreos.com/v1
|
|
|
|
+ kind: operatorgroup
|
|
|
|
+ namespace: "{{ op.op_nsp }}"
|
|
|
|
+ name: "{{ op.op_nsp }}"
|
|
|
|
+ definition:
|
|
|
|
+ spec:
|
|
|
|
+ targetNamespaces: "{{ og_spec }}"
|
|
|
|
+ when: (found_opgrp.resources | length) == 0
|
|
|
|
+
|
|
|
|
+ # create a subscription if not there, and wait for the CSV
|
|
|
|
+ - name: Also make sure there is a subscription
|
|
|
|
+ k8s:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: operators.coreos.com/v1alpha1
|
|
|
|
+ kind: subscription
|
|
|
|
+ namespace: "{{ op.op_nsp }}"
|
|
|
|
+ name: "{{ op.op_pkg }}"
|
|
|
|
+ definition:
|
|
|
|
+ spec:
|
|
|
|
+ source: "{{ op.op_cat }}"
|
|
|
|
+ sourceNamespace: openshift-marketplace
|
|
|
|
+ name: "{{ op.op_pkg }}"
|
|
|
|
+ channel: "{{ op.op_chn }}"
|
|
|
|
+ installPlanApproval: Automatic
|
|
|
|
+
|
|
|
|
+ # TODO: Finish this at some point.
|
|
|
|
+ #- name: Wait for installPlan to show up
|
|
|
|
+ # k8s_info:
|
|
|
|
+ # kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ # validate_certs: no
|
|
|
|
+ # api_version: operators.coreos.com/v1alpha1
|
|
|
|
+ # kind: installplan
|
|
|
|
+ # namespace: "{{ op_nsp }}"
|
|
|
|
+ # register: installplan
|
|
|
|
+ # until:
|
|
|
|
+ # - installplan.resources is defined
|
|
|
|
+ # - (installplan.resources | length) > 0
|
|
|
|
+ # - installplan.resources[0].spec.approved
|
|
|
|
+ # retries: 12
|
|
|
|
+ # delay: 10
|
|
|
|
+
|
|
|
|
+ - name: Wait for CSV to show up and complete
|
|
|
|
+ k8s_info:
|
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ validate_certs: no
|
|
|
|
+ api_version: operators.coreos.com/v1alpha1
|
|
|
|
+ kind: clusterserviceversion
|
|
|
|
+ namespace: "{{ op.op_nsp }}"
|
|
|
|
+ name: "{{ op.desired_csv }}"
|
|
|
|
+ register: new_csv
|
|
|
|
+ until:
|
|
|
|
+ - new_csv.resources is defined
|
|
|
|
+ - (new_csv.resources | length) > 0
|
|
|
|
+ - new_csv.resources[0].status is defined
|
|
|
|
+ - new_csv.resources[0].status.phase == "Succeeded"
|
|
|
|
+ retries: 30
|
|
|
|
+ delay: 10
|
|
|
|
+
|
|
|
|
+ # TODO: Finish this at some point.
|
|
|
|
+ #- name: Finally, wait for the pod
|
|
|
|
+ # k8s_info:
|
|
|
|
+ # kubeconfig: tmp/kubeconfig-ocp4
|
|
|
|
+ # validate_certs: no
|
|
|
|
+ # api_version: v1
|
|
|
|
+ # kind: pod
|
|
|
|
+ # namespace: rhsso
|
|
|
|
+ # label_selectors:
|
|
|
|
+ # - name = rhsso-operator
|
|
|
|
+ # register: sso_pod
|
|
|
|
+ # until:
|
|
|
|
+ # - sso_pod.resources is defined
|
|
|
|
+ # - (sso_pod.resources | length) > 0
|
|
|
|
+ # - sso_pod.resources[0].status is defined
|
|
|
|
+ # - sso_pod.resources[0].status.phase == "Running"
|
|
|
|
+ # retries: 30
|
|
|
|
+ # delay: 10
|
|
|
|
+
|
|
|
|
+ - debug:
|
|
|
|
+ msg: Operator {{ op.op_pkg }} deployed in namespace {{ op.op_nsp }} with CSV {{ op.desired_csv }}!
|
|
|
|
+
|
|
|
|
+ when: found_csv is not defined or (found_csv | length) == 0
|
|
|
|
+...
|