From d46338299a2785733393f0e263a34ff93d754e74 Mon Sep 17 00:00:00 2001 From: Judd Maltin Date: Wed, 3 Dec 2025 15:29:41 -0500 Subject: [PATCH] ocp4_workload_gitops_bootstrap: support bootstrap/boostrap-infra/bootstrap-tenant --- .../defaults/main.yml | 32 +++- .../tasks/workload.yml | 140 +++++++++++------- .../templates/application.yaml.j2 | 2 +- 3 files changed, 119 insertions(+), 55 deletions(-) diff --git a/roles/ocp4_workload_gitops_bootstrap/defaults/main.yml b/roles/ocp4_workload_gitops_bootstrap/defaults/main.yml index b4c54d4..e9e661d 100644 --- a/roles/ocp4_workload_gitops_bootstrap/defaults/main.yml +++ b/roles/ocp4_workload_gitops_bootstrap/defaults/main.yml @@ -1,17 +1,47 @@ --- ocp4_workload_gitops_bootstrap_repo_url: http://gitea:3000/user/bootstrap ocp4_workload_gitops_bootstrap_repo_revision: main + +# Examples to support multi-tenancy: +# +# Example 1: Backwards compatibility. Deploys INFRA and N number of tenants +# ocp4_workload_gitops_bootstrap_application_name: 'bootstrap' +# ocp4_workload_gitops_bootstrap_repo_path: "" +# ocp4_workload_gitops_bootstrap_helm_values: +# user: +# count: 3 +# +# Example 2: Deploy ONLY the infra: +# ocp4_workload_gitops_bootstrap_application_name: 'bootstrap-infra' +# ocp4_workload_gitops_bootstrap_repo_path: infra +# +# Example 3: Deploy ONE tenant +# ocp4_workload_gitops_bootstrap_application_name: 'bootstrap-tenant-{{ guid }}' +# ocp4_workload_gitops_bootstrap_repo_path: tenant + +ocp4_workload_gitops_bootstrap_application_name: bootstrap ocp4_workload_gitops_bootstrap_repo_path: "" +#'bootstrap-tenant-{{ guid }}' or 'bootstrap-infra' or 'bootstrap' + +# We cannot do k8s_info on annotations, +# so when deploying openshift_gitops, +# you need to enable ocp4_workload_openshift_gitops_resource_tracking_method: "annotations+label" ocp4_workload_gitops_bootstrap_namespace: openshift-gitops # Helm values to override in the ArgoCD bootstrap application. ocp4_workload_gitops_bootstrap_helm_values: [] +# in Argo, application "health" is more important than "sync" +# During development, it's usually safe to ignore "sync" errors in bootstrap +# Developers must clean up sync errors before promoting to prod ocp4_workload_gitops_bootstrap_health_retries: 60 ocp4_workload_gitops_bootstrap_health_ignore: true # wait 15 mninutes for apps to roll out ocp4_workload_gitops_bootstrap_application_wait: true ocp4_workload_gitops_bootstrap_application_health_retries: 90 -ocp4_workload_gitops_bootstrap_application_health_ignore: true +# you really do want your apps to be healthy +ocp4_workload_gitops_bootstrap_application_health_required: true + +ocp4_workload_gitops_bootstrap_application_sync_required: true # false is great for development diff --git a/roles/ocp4_workload_gitops_bootstrap/tasks/workload.yml b/roles/ocp4_workload_gitops_bootstrap/tasks/workload.yml index d703470..94bbaae 100644 --- a/roles/ocp4_workload_gitops_bootstrap/tasks/workload.yml +++ b/roles/ocp4_workload_gitops_bootstrap/tasks/workload.yml @@ -5,21 +5,53 @@ deployer: domain: "{{ openshift_cluster_ingress_domain }}" apiUrl: "{{ openshift_api_url }}" + guid: "{{ guid }}" - name: Debug _ocp4_workload_gitops_bootstrap_deployer_values ansible.builtin.debug: msg: "{{ _ocp4_workload_gitops_bootstrap_deployer_values | to_yaml }}" +- name: Report boostrap application name + ansible.builtin.debug: + msg: "Deploying boostrap application: {{ ocp4_workload_gitops_bootstrap_application_name }}" + +- name: Set App paths for 'bootstrap', infra + tenants deployment scenario + when: ocp4_workload_gitops_bootstrap_application_name == 'bootstrap' + ansible.builtin.set_fact: + ocp4_workload_gitops_bootstrap_repo_path: "bootstrap" + +- name: Set App path for 'bootstrap-infra', infra only deployment scenario + when: ocp4_workload_gitops_bootstrap_application_name == 'bootstrap-infra' + ansible.builtin.set_fact: + ocp4_workload_gitops_bootstrap_repo_path: "infra" + +- name: "Set App path and name for 'bootstrap-tenant', infra only deployment scenario" + when: ocp4_workload_gitops_bootstrap_application_name == 'bootstrap-tenant' + ansible.builtin.set_fact: + ocp4_workload_gitops_bootstrap_repo_path: "tenant" + ocp4_workload_gitops_bootstrap_application_name: "bootstrap-tenant-{{ guid }}" + - name: Create bootstrap ArgoCD application kubernetes.core.k8s: state: present template: application.yaml.j2 +# Bootstrap Application created has no labels. Consider adding. +# +# Child applications are tracked: +# +# creates tracking annotations like this: +# annotations: +# argocd.argoproj.io/tracking-id: 'infra-bootstrap:argoproj.io/Application:openshift-gitops/bastion' +# +# annotations: +# argocd.argoproj.io/tracking-id: 'bootstrap:argoproj.io/Application:openshift-gitops/infra-bootstrap' + - name: Wait until bootstrap ArgoCD application is healthy and synced kubernetes.core.k8s_info: api_version: argoproj.io/v1alpha1 kind: Application - name: bootstrap + name: "{{ ocp4_workload_gitops_bootstrap_application_name }}" namespace: openshift-gitops register: argocd_bootstrap retries: "{{ ocp4_workload_gitops_bootstrap_health_retries }}" @@ -29,13 +61,15 @@ - argocd_bootstrap.resources is defined - argocd_bootstrap.resources | length > 0 - argocd_bootstrap.resources[0].status is defined + - argocd_bootstrap.resources[0].status.health.status is defined - argocd_bootstrap.resources[0].status.health.status == "Healthy" + - argocd_bootstrap.resources[0].status.sync.status is defined - argocd_bootstrap.resources[0].status.sync.status == "Synced" ignore_errors: "{{ ocp4_workload_gitops_bootstrap_health_ignore | bool }}" -- name: Pause for a minute while the bootstrap app deploys - ansible.builtin.pause: - seconds: 60 +# - name: Pause for a minute while the bootstrap app deploys +# ansible.builtin.pause: +# seconds: 60 - name: Validate all applications with our label in any namespace are healthy and synced when: ocp4_workload_gitops_bootstrap_application_wait | bool @@ -43,7 +77,7 @@ api_version: argoproj.io/v1alpha1 kind: Application label_selectors: - - "demo.redhat.com/application" + - "app.kubernetes.io/instance={{ ocp4_workload_gitops_bootstrap_application_name }}" register: _all_apps delay: 10 retries: "{{ ocp4_workload_gitops_bootstrap_application_health_retries }}" @@ -57,51 +91,51 @@ ####### ####### Begin processing GitOps output ####### - -- name: Retrieve ConfigMaps with the demo.redhat.com/userinfo label - kubernetes.core.k8s_info: - api_version: v1 - kind: ConfigMap - label_selectors: - - "demo.redhat.com/userinfo" - register: cm_userinfo - -- name: If ConfigMaps were found, process them - when: - - cm_userinfo.resources is defined - - cm_userinfo.resources | length | int > 0 - block: - - name: Add to agnosticd_user_info all data from ConfigMaps except configmap.data.users_json data - agnosticd.core.agnosticd_user_info: - data: >- - {{ item | dict2items | selectattr('key', 'ne', 'users_json') | items2dict }} - loop: "{{ cm_userinfo.resources | map(attribute='data') }}" - - - name: Prepare data_user_json to add to agnosticd_user_info - ansible.builtin.debug: - msg: "Prepare data_user_json to add to agnosticd_user_info" - - - name: Merge list of all users_json data from all ConfigMaps that have data.users_json - ansible.builtin.set_fact: - data_users_json: "{{ data_users_json | default([]) | combine(item.data.users_json | from_json, recursive=True) }}" - loop: "{{ cm_userinfo.resources }}" - when: item.data.users_json is defined - - - name: Handle data_users_json data - when: data_users_json is defined - block: - - name: Debug merged data_users_json data - ansible.builtin.debug: - msg: "{{ data_users_json }}" - - - name: Add to agnosticd_user_info all configmap.data.users_json ConfigMap data - agnosticd.core.agnosticd_user_info: - user: "{{ item.key }}" - data: - "{{ item.value }}" - loop: "{{ data_users_json.users | dict2items }}" - when: data_users_json is defined - -- name: Debug user_data - ansible.builtin.debug: - msg: "{{ lookup('agnosticd_user_data', '*') }}" +# +# - name: Retrieve ConfigMaps with the demo.redhat.com/userinfo label +# kubernetes.core.k8s_info: +# api_version: v1 +# kind: ConfigMap +# label_selectors: +# - "demo.redhat.com/userinfo" +# register: cm_userinfo +# +# - name: If ConfigMaps were found, process them +# when: +# - cm_userinfo.resources is defined +# - cm_userinfo.resources | length | int > 0 +# block: +# - name: Add to agnosticd_user_info all data from ConfigMaps except configmap.data.users_json data +# agnosticd.core.agnosticd_user_info: +# data: >- +# {{ item | dict2items | selectattr('key', 'ne', 'users_json') | items2dict }} +# loop: "{{ cm_userinfo.resources | map(attribute='data') }}" +# +# - name: Prepare data_user_json to add to agnosticd_user_info +# ansible.builtin.debug: +# msg: "Prepare data_user_json to add to agnosticd_user_info" +# +# - name: Merge list of all users_json data from all ConfigMaps that have data.users_json +# ansible.builtin.set_fact: +# data_users_json: "{{ data_users_json | default([]) | combine(item.data.users_json | from_json, recursive=True) }}" +# loop: "{{ cm_userinfo.resources }}" +# when: item.data.users_json is defined +# +# - name: Handle data_users_json data +# when: data_users_json is defined +# block: +# - name: Debug merged data_users_json data +# ansible.builtin.debug: +# msg: "{{ data_users_json }}" +# +# - name: Add to agnosticd_user_info all configmap.data.users_json ConfigMap data +# agnosticd.core.agnosticd_user_info: +# user: "{{ item.key }}" +# data: +# "{{ item.value }}" +# loop: "{{ data_users_json.users | dict2items }}" +# when: data_users_json is defined +# +# - name: Debug user_data +# ansible.builtin.debug: +# msg: "{{ lookup('agnosticd_user_data', '*') }}" diff --git a/roles/ocp4_workload_gitops_bootstrap/templates/application.yaml.j2 b/roles/ocp4_workload_gitops_bootstrap/templates/application.yaml.j2 index 7a2f1bc..9836702 100644 --- a/roles/ocp4_workload_gitops_bootstrap/templates/application.yaml.j2 +++ b/roles/ocp4_workload_gitops_bootstrap/templates/application.yaml.j2 @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: bootstrap + name: "{{ ocp4_workload_gitops_bootstrap_application_name }}" namespace: {{ ocp4_workload_gitops_bootstrap_namespace }} spec: project: default