main.yml 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. ---
  2. # Ensures all the operator artifacts are created and waits for CSV to succeed.
  3. #
  4. # The following variables must exist:
  5. #
  6. # added_operators: (list)
  7. # - catalog: the catalog of the manifest
  8. # catalog_namespace: (optional) catalog namespace (defaults to openshift-marketplace)
  9. # package: the name of the packagemanifest
  10. # subscription: the name of the operatorgroup and subscription (optional, defaults to package)
  11. # channel: which channel to install from
  12. # namespace: target namespace for subscription
  13. # desired_csv: for verification - wait for this CSV to appear
  14. # og_namespaces: (list) operatorgroup namespaces
  15. # approval: Automatic (default) or Manual
  16. #
  17. # This role must then be applied as:
  18. #
  19. # - include_role:
  20. # name: deploy-operators
  21. # loop: "{{ added_operators }}"
  22. # loop_control:
  23. # loop_var: role
  24. #
  25. # What this means is that each item of added_operators is expected to be
  26. # placed in the "role" variable prior to iterating over this role.
  27. #
  28. # OPTIONAL:
  29. #
  30. # kubeadmin_config kubeadmin (or other admin) credentials (tmp/kubeconfig-ocp4)
  31. #
  32. # NOTE: Do NOT test by checking for presence of API resources - they do not
  33. # always get cleaned up, so it might report a false positive.
  34. #
  35. - name: Tell what is happening
  36. ansible.builtin.pause:
  37. prompt: |
  38. *******************************************************************************
  39. * Deploying operator {{ role.package }} to namespace {{ role.namespace }}
  40. *******************************************************************************
  41. seconds: 0
  42. - name: Make sure the namespace is there
  43. kubernetes.core.k8s:
  44. kubeconfig: "{{ kubeadmin_config }}"
  45. validate_certs: no
  46. api_version: v1
  47. kind: namespace
  48. name: "{{ role.namespace }}"
  49. - name: Verify if the namespace has an OperatorGroup already
  50. kubernetes.core.k8s_info:
  51. kubeconfig: "{{ kubeadmin_config }}"
  52. validate_certs: no
  53. api_version: operators.coreos.com/v1
  54. kind: operatorgroup
  55. namespace: "{{ role.namespace }}"
  56. register: found_opgrp
  57. - name: Show the operator groups found at verbosity 2+
  58. debug:
  59. var: found_opgrp
  60. verbosity: 2
  61. - name: The OperatorGroup must have a matching targetNamespaces if it exists already, or we can not continue.
  62. ansible.builtin.assert:
  63. that:
  64. - >
  65. (role.og_namespaces is defined and
  66. found_opgrp.resources[0].spec.targetNamespaces is defined and
  67. found_opgrp.resources[0].spec.targetNamespaces == role.og_namespaces) or
  68. ((role.og_namespaces is not defined or role.og_namespaces == []) and
  69. found_opgrp.resources[0].spec.targetNamespaces is not defined)
  70. success_msg: "Found existing OperatorGroup with matching targetNamespaces."
  71. fail_msg: "FATAL: OperatorGroup already exists but does not have matching targetNamespaces."
  72. when:
  73. - found_opgrp.resources is defined
  74. - found_opgrp.resources[0] is defined
  75. - found_opgrp.resources[0].spec is defined
  76. - name: If not there yet, create an OperatorGroup
  77. kubernetes.core.k8s:
  78. kubeconfig: "{{ kubeadmin_config }}"
  79. validate_certs: no
  80. api_version: operators.coreos.com/v1
  81. kind: operatorgroup
  82. namespace: "{{ role.namespace }}"
  83. name: "{{ role.subscription | default(role.package) }}"
  84. definition:
  85. spec:
  86. targetNamespaces: "{{ role.og_namespaces | default(omit) }}"
  87. when:
  88. - >
  89. found_opgrp.resources is not defined or
  90. found_opgrp.resources[0] is not defined
  91. - name: Check if installPlans exist already before fondling around with subscriptions
  92. kubernetes.core.k8s_info:
  93. kubeconfig: "{{ kubeadmin_config }}"
  94. validate_certs: no
  95. api_version: operators.coreos.com/v1alpha1
  96. kind: installplan
  97. namespace: "{{ role.namespace }}"
  98. register: installplan_pre
  99. - name: Remember the installPlan(s) found prior to fondling around with subscriptions as a fact
  100. ansible.builtin.set_fact:
  101. sub_ip_pre: "{{ installplan_pre.resources | selectattr('metadata.ownerReferences.0.name', 'in', (role.subscription | default(role.package))) | sort(attribute='metadata.creationTimestamp', reverse=True) }}"
  102. - name: Show the installplan(s) found at verbosity 2+
  103. debug:
  104. var: sub_ip_pre
  105. verbosity: 2
  106. - name: Also make sure there is a subscription
  107. kubernetes.core.k8s:
  108. kubeconfig: "{{ kubeadmin_config }}"
  109. validate_certs: no
  110. api_version: operators.coreos.com/v1alpha1
  111. kind: subscription
  112. namespace: "{{ role.namespace }}"
  113. name: "{{ role.subscription | default(role.package) }}"
  114. definition:
  115. spec:
  116. source: "{{ role.catalog }}"
  117. sourceNamespace: "{{ role.catalog_namespace | default('openshift-marketplace') }}"
  118. name: "{{ role.package }}"
  119. channel: "{{ role.channel }}"
  120. startingCSV: "{{ role.desired_csv }}"
  121. installPlanApproval: "{{ role.approval | default('Automatic') }}"
  122. register: subscription
  123. - name: Handle installPlan if the subscription changed anything
  124. block:
  125. - name: Wait for installPlan to show up
  126. kubernetes.core.k8s_info:
  127. kubeconfig: "{{ kubeadmin_config }}"
  128. validate_certs: no
  129. api_version: operators.coreos.com/v1alpha1
  130. kind: installplan
  131. namespace: "{{ role.namespace }}"
  132. register: installplan
  133. until:
  134. - installplan.resources is defined
  135. - (installplan.resources | length) > 0
  136. - >
  137. (installplan.resources |
  138. selectattr('metadata.ownerReferences.0.name', 'in', (role.subscription | default(role.package))) |
  139. length) > (sub_ip_pre | length)
  140. retries: 12
  141. delay: 10
  142. - name: Remember the installPlan(s) found after the subscription has been modified
  143. ansible.builtin.set_fact:
  144. sub_ip_post: "{{ installplan.resources | selectattr('metadata.ownerReferences.0.name', 'in', (role.subscription | default(role.package))) | sort(attribute='metadata.creationTimestamp', reverse=True) }}"
  145. - name: Show the installplan(s) found at verbosity 2+
  146. debug:
  147. var: sub_ip_post
  148. verbosity: 2
  149. - name: Remember the latest installPlan name as a new fact
  150. ansible.builtin.set_fact:
  151. latest_install_plan: "{{ sub_ip_post[0].metadata.name }}"
  152. - name: Announce the installPlan name
  153. ansible.builtin.debug:
  154. msg: Found installPlan {{ latest_install_plan }}.
  155. - name: Approve the installPlan if the approval was Manual
  156. kubernetes.core.k8s_json_patch:
  157. kubeconfig: "{{ kubeadmin_config }}"
  158. validate_certs: no
  159. api_version: operators.coreos.com/v1alpha1
  160. kind: installplan
  161. namespace: "{{ role.namespace }}"
  162. name: "{{ latest_install_plan }}"
  163. patch:
  164. - op: replace
  165. path: /spec/approved
  166. value: true
  167. when: role.approval == "Manual"
  168. when: subscription.changed
  169. - name: Wait for CSV to show up and complete
  170. kubernetes.core.k8s_info:
  171. kubeconfig: "{{ kubeadmin_config }}"
  172. validate_certs: no
  173. api_version: operators.coreos.com/v1alpha1
  174. kind: clusterserviceversion
  175. namespace: "{{ role.namespace }}"
  176. name: "{{ role.desired_csv }}"
  177. register: new_csv
  178. until:
  179. - new_csv.resources is defined
  180. - (new_csv.resources | length) > 0
  181. - new_csv.resources[0].status is defined
  182. - new_csv.resources[0].status.phase == "Succeeded"
  183. retries: 30
  184. delay: 10
  185. ...