main.yml 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. ---
  2. # Ensures all the operator artifacts are created and waits for CSV to succeed.
  3. #
  4. # The following variables must exist:
  5. #
  6. # op:
  7. # desired_csv
  8. # op_nsp
  9. # op_cat
  10. # op_pkg
  11. # op_chn
  12. # op_mod
  13. #
  14. # NOTE: Do NOT test by checking for presence of API resources - they do not always get cleaned up.
  15. - debug:
  16. msg: Deploying operator {{ op.op_pkg }} in namespace {{ op.op_nsp }}...
  17. # See if the CSV is available already (anywhere), meaning the operator is already installed.
  18. - name: Check if the CSV exists already
  19. k8s_info:
  20. kubeconfig: tmp/kubeconfig-ocp4
  21. validate_certs: no
  22. api_version: operators.coreos.com/v1alpha1
  23. kind: clusterserviceversion
  24. register: all_csv
  25. - name: Find the wanted CSV among all CSVs
  26. set_fact:
  27. found_csv: '{{ (all_csv | community.general.json_query("resources[?contains(metadata.name, `" + op.op_pkg + ".`)]")) }}'
  28. when:
  29. - all_csv.resources is defined
  30. - (all_csv.resources | length) > 0
  31. - name: Get details about the CSV if found
  32. set_fact:
  33. csv_ns: "{{ found_csv[0] | community.general.json_query('metadata.namespace') }}"
  34. csv_name: "{{ found_csv[0] | community.general.json_query('metadata.name') }}"
  35. when:
  36. - found_csv is defined
  37. - (found_csv | length) > 0
  38. - debug:
  39. msg: Operator {{ op.op_pkg }} is already installed in {{ csv_ns }} as {{ csv_name }} (desired_csv == {{ op.desired_csv }}).
  40. when:
  41. - csv_ns is defined
  42. - csv_name is defined
  43. - name: Only proceed here if the CSV was not found anywhere yet
  44. block:
  45. # Check if package provides desired_csv in any of the channels
  46. - name: Get packagemanifest
  47. k8s_info:
  48. kubeconfig: tmp/kubeconfig-ocp4
  49. validate_certs: no
  50. api_version: packages.operators.coreos.com/v1
  51. kind: packagemanifest
  52. namespace: openshift-marketplace
  53. name: "{{ op.op_pkg }}"
  54. register: pkg_mft
  55. - name: Search for any channels that provide desired_csv
  56. set_fact:
  57. found_chn: '{{ (pkg_mft | community.general.json_query("resources[0].status.channels[?currentCSV == `" + op.desired_csv + "`].name")) }}'
  58. when:
  59. - pkg_mft is defined
  60. - pkg_mft.resources | length > 0
  61. - name: Fail if no channel provides the desired_csv
  62. fail:
  63. msg: No {{ op.op_pkg }} channel provides {{ op.desired_csv }}
  64. when:
  65. - found_chn is defined
  66. - found_chn | length == 0
  67. - name: Fail if selected channel does not provide the desired_csv
  68. fail:
  69. msg: Operator {{ op.op_pkg }} selected channel {{ op.op_chn }} does not provide {{ op.desired_csv }} - {{ found_chn }}
  70. when:
  71. - found_chn is defined
  72. - found_chn | length > 0
  73. - op.op_chn not in found_chn
  74. # Create the namespace if necessary
  75. - name: Make sure the namespace is there
  76. k8s:
  77. kubeconfig: tmp/kubeconfig-ocp4
  78. validate_certs: no
  79. api_version: v1
  80. kind: namespace
  81. name: "{{ op.op_nsp }}"
  82. # Check for operator group - if existing, make sure it's compatible; otherwise create it
  83. - name: See if there are any OperatorGroups
  84. k8s_info:
  85. kubeconfig: tmp/kubeconfig-ocp4
  86. validate_certs: no
  87. api_version: operators.coreos.com/v1
  88. kind: operatorgroup
  89. namespace: "{{ op.op_nsp }}"
  90. register: found_opgrp
  91. - name: Die if more than one OG
  92. ansible.builtin.fail:
  93. msg: More than one OperatorGroup found in project.
  94. when: (found_opgrp.resources | length) > 1
  95. - name: Die if op_mod is not recognised
  96. ansible.builtin.fail:
  97. msg: Unrecognised op.op_mod ({{ op.op_mod }})
  98. when: op.op_mod not in ["all", "self"]
  99. - name: Die if op_mod does not match found OG mode
  100. ansible.builtin.fail:
  101. msg: Found OG mode does not match required ({{ op.op_mod }})
  102. when: |
  103. ((found_opgrp.resources | length) == 1 and op.op_mod == "all" and found_opgrp.resources[0].status.namespaces != [""]) or
  104. ((found_opgrp.resources | length) == 1 and op.op_mod == "self" and found_opgrp.resources[0].status.namespaces != [op.op_nsp])
  105. - name: Set fact for namespaces of OG if we require all
  106. set_fact:
  107. og_spec: []
  108. when:
  109. - op.op_mod == "all"
  110. - (found_opgrp.resources | length) == 0
  111. - name: Set fact for namespaces of OG if we require self
  112. set_fact:
  113. og_spec: ["{{op.op_nsp}}"]
  114. when:
  115. - op.op_mod == "self"
  116. - (found_opgrp.resources | length) == 0
  117. - name: Create the OperatorGroup if not there
  118. k8s:
  119. kubeconfig: tmp/kubeconfig-ocp4
  120. validate_certs: no
  121. api_version: operators.coreos.com/v1
  122. kind: operatorgroup
  123. namespace: "{{ op.op_nsp }}"
  124. name: "{{ op.op_nsp }}"
  125. definition:
  126. spec:
  127. targetNamespaces: "{{ og_spec }}"
  128. when: (found_opgrp.resources | length) == 0
  129. # create a subscription if not there, and wait for the CSV
  130. - name: Also make sure there is a subscription
  131. k8s:
  132. kubeconfig: tmp/kubeconfig-ocp4
  133. validate_certs: no
  134. api_version: operators.coreos.com/v1alpha1
  135. kind: subscription
  136. namespace: "{{ op.op_nsp }}"
  137. name: "{{ op.op_pkg }}"
  138. definition:
  139. spec:
  140. source: "{{ op.op_cat }}"
  141. sourceNamespace: openshift-marketplace
  142. name: "{{ op.op_pkg }}"
  143. channel: "{{ op.op_chn }}"
  144. installPlanApproval: Automatic
  145. # TODO: Finish this at some point.
  146. #- name: Wait for installPlan to show up
  147. # k8s_info:
  148. # kubeconfig: tmp/kubeconfig-ocp4
  149. # validate_certs: no
  150. # api_version: operators.coreos.com/v1alpha1
  151. # kind: installplan
  152. # namespace: "{{ op_nsp }}"
  153. # register: installplan
  154. # until:
  155. # - installplan.resources is defined
  156. # - (installplan.resources | length) > 0
  157. # - installplan.resources[0].spec.approved
  158. # retries: 12
  159. # delay: 10
  160. - name: Wait for CSV to show up and complete
  161. k8s_info:
  162. kubeconfig: tmp/kubeconfig-ocp4
  163. validate_certs: no
  164. api_version: operators.coreos.com/v1alpha1
  165. kind: clusterserviceversion
  166. namespace: "{{ op.op_nsp }}"
  167. name: "{{ op.desired_csv }}"
  168. register: new_csv
  169. until:
  170. - new_csv.resources is defined
  171. - (new_csv.resources | length) > 0
  172. - new_csv.resources[0].status is defined
  173. - new_csv.resources[0].status.phase == "Succeeded"
  174. retries: 30
  175. delay: 10
  176. # TODO: Finish this at some point.
  177. #- name: Finally, wait for the pod
  178. # k8s_info:
  179. # kubeconfig: tmp/kubeconfig-ocp4
  180. # validate_certs: no
  181. # api_version: v1
  182. # kind: pod
  183. # namespace: rhsso
  184. # label_selectors:
  185. # - name = rhsso-operator
  186. # register: sso_pod
  187. # until:
  188. # - sso_pod.resources is defined
  189. # - (sso_pod.resources | length) > 0
  190. # - sso_pod.resources[0].status is defined
  191. # - sso_pod.resources[0].status.phase == "Running"
  192. # retries: 30
  193. # delay: 10
  194. - debug:
  195. msg: Operator {{ op.op_pkg }} deployed in namespace {{ op.op_nsp }} with CSV {{ op.desired_csv }}!
  196. when: found_csv is not defined or (found_csv | length) == 0
  197. ...