diff --git a/charts/orchestrator/templates/_cr_lifecycle_helper.tpl b/charts/orchestrator/templates/_cr_lifecycle_helper.tpl index 3d2e33a5..8904a6fc 100644 --- a/charts/orchestrator/templates/_cr_lifecycle_helper.tpl +++ b/charts/orchestrator/templates/_cr_lifecycle_helper.tpl @@ -1,26 +1,18 @@ {{- define "manage-cr-lifecycle-on-action" }} {{- $resourceAPIGroup := printf "%s.%s" .kinds .apiGroup }} {{- $releaseNameKind := printf "%s-%s" .release.Name .kind |lower }} - {{ if or .isEnabled (and (not .isEnabled) (and .hasCRDInstalled (not (empty (lookup (printf "%s/%s" .apiGroup .groupVersion) .kind (dig "targetNamespace" "" . ) .resourceName ))))) }} + {{- if .isEnabled }} --- apiVersion: v1 kind: ServiceAccount metadata: name: {{ $releaseNameKind }} namespace: {{ .release.Namespace }} - annotations: - "helm.sh/hook": {{ if .isEnabled }}pre-delete,post-install,post-upgrade,post-rollback{{ else }}pre-upgrade,pre-rollback{{ end }} - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed - "helm.sh/hook-weight": "-1" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ $releaseNameKind }} - annotations: - "helm.sh/hook": {{ if .isEnabled }}pre-delete,post-install,post-upgrade,post-rollback{{ else }}pre-upgrade,pre-rollback{{ end }} - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed - "helm.sh/hook-weight": "0" rules: - apiGroups: - apiextensions.k8s.io @@ -33,21 +25,25 @@ rules: resources: - {{ .kinds |lower}} verbs: - - get - - list - - delete - patch - update - create + - get + - list + - delete + - watch + - apiGroups: + - batch + resources: + - cronjobs + verbs: + - delete + - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $releaseNameKind }} - annotations: - "helm.sh/hook": {{ if .isEnabled }}pre-delete,post-install,post-upgrade,post-rollback{{ else }}pre-upgrade,pre-rollback{{ end }} - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed - "helm.sh/hook-weight": "0" subjects: - kind: ServiceAccount name: {{ $releaseNameKind }} @@ -56,73 +52,74 @@ roleRef: kind: ClusterRole name: {{ $releaseNameKind }} apiGroup: rbac.authorization.k8s.io - {{- if .isEnabled }} --- apiVersion: batch/v1 -kind: Job +kind: CronJob metadata: - name: {{ trunc -57 (printf "%s-%s" $releaseNameKind (.release.IsInstall | ternary "install" "upgrade" ) ) }} # Fixes https://github.com/parodos-dev/orchestrator-helm-chart/issues/160 + name: {{ trunc -52 (printf "%s-reconcile" $releaseNameKind | trimPrefix "-" | trimPrefix "_" ) }} # Fixes https://github.com/parodos-dev/orchestrator-helm-chart/issues/160 # job name is used in the spec.template.metadata.labels, and labels cannot be more than 63 characters https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ namespace: {{ .release.Namespace }} - annotations: - "helm.sh/hook": post-install,post-upgrade,post-rollback - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - "helm.sh/hook-weight": "1" + labels: + "orchestrator.rhdh.redhat.com/reconciles": {{ $resourceAPIGroup }} spec: - template: - metadata: - name: {{ printf "%s-upgrade" $releaseNameKind }} + schedule: '* * * * *' #run every minute + concurrencyPolicy: Replace + successfulJobsHistoryLimit: 0 + jobTemplate: spec: - serviceAccountName: {{ $releaseNameKind }} - containers: - - name: job - image: registry.redhat.io/openshift4/ose-cli:latest - env: - - name: MANIFEST - value: {{ .manifest }} - command: - - "bin/bash" - - "-c" - args: - - | - echo "Update Job for CR {{ .kind }} of {{ $resourceAPIGroup }} started" - echo "Checking for availability of CRD {{ printf "%s.%s" .kinds .apiGroup }}" - count=60 - while [[ count -ne 0 ]] - do - kubectl get crd {{ printf "%s.%s" .kinds .apiGroup }} -oname - if [[ $? -eq 0 ]]; then - echo $MANIFEST | base64 -d | kubectl apply -f - - if [[ $? -eq 0 ]]; then - echo "Update Job finished" - exit 0 - fi + template: + spec: + restartPolicy: OnFailure + serviceAccountName: {{ $releaseNameKind }} + containers: + - name: job + image: registry.redhat.io/openshift4/ose-cli:latest + env: + - name: MANIFEST + value: {{ .manifest }} + command: + - "bin/bash" + - "-c" + args: + - | + echo "Update Job for CR {{ .kind }} of {{ $resourceAPIGroup }} started" + echo "Checking for availability of CRD {{ printf "%s.%s" .kinds .apiGroup }}" + count=60 + while [[ count -ne 0 ]] + do + kubectl get crd {{ printf "%s.%s" .kinds .apiGroup }} -oname + if [[ $? -eq 0 ]]; then + echo $MANIFEST | base64 -d | kubectl apply -f - + if [[ $? -eq 0 ]]; then + echo "Update Job finished" + exit 0 + fi + exit 1 + fi + ((count--)) + sleep 5 + done + echo "Could not find CRD {{ printf "%s.%s" .kinds .apiGroup }} deployed" exit 1 - fi - ((count--)) - sleep 5 - done - echo "Could not find CRD {{ printf "%s.%s" .kinds .apiGroup }} deployed" - exit 1 - - restartPolicy: Never - {{- end }} + {{- end }} + {{ if or (.isEnabled) (and (not .isEnabled) (and .hasCRDInstalled (not (empty (lookup (printf "%s/%s" .apiGroup .groupVersion) .kind (dig "targetNamespace" "" . ) .resourceName ))))) }} --- apiVersion: batch/v1 kind: Job metadata: - name: {{ trunc -57 (printf "%s-delete" $releaseNameKind) }} # Fixes https://github.com/parodos-dev/orchestrator-helm-chart/issues/160 + name: {{ trunc -57 (printf "%s-delete" $releaseNameKind) | trimPrefix "-" | trimPrefix "_" }} # Fixes https://github.com/parodos-dev/orchestrator-helm-chart/issues/160 # job name is used in the spec.template.metadata.labels, and labels cannot be more than 63 characters https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ namespace: {{ .release.Namespace }} annotations: "helm.sh/hook": {{ if .isEnabled }}pre-delete{{ end }}{{ if and (not .isEnabled) (not (empty (lookup (printf "%s/%s" .apiGroup .groupVersion) .kind (dig "targetNamespace" "" . ) .resourceName ))) }}pre-upgrade,pre-rollback{{ end }} - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + "helm.sh/hook-delete-policy": before-hook-creation "helm.sh/hook-weight": "1" spec: template: metadata: name: {{ $releaseNameKind }} spec: + restartPolicy: Never serviceAccountName: {{ $releaseNameKind }} containers: - name: cleanup @@ -135,12 +132,12 @@ spec: echo "Cleanup Job for CR {{ .kind }} of {{ $resourceAPIGroup }} started" kubectl get crd {{ $resourceAPIGroup }} if [ $? -eq 0 ]; then + kubectl delete cronjob -l orchestrator.rhdh.redhat.com/reconciles={{ $resourceAPIGroup }} -n {{ .release.Namespace }} # Ensure no race condition happens where a cronjob's spawned job creates the CR after the delete job is completed and while helm is processing the other delete jobs kubectl get {{ if (hasKey . "targetNamespace") }} -n {{ .targetNamespace }} {{ end }} {{ $resourceAPIGroup }} {{ .resourceName }} if [ $? -eq 0 ]; then - kubectl delete {{ if (hasKey . "targetNamespace") }} -n {{ .targetNamespace }} {{ end }} {{ $resourceAPIGroup }} {{ .resourceName }} || exit 1 + kubectl delete {{ if (hasKey . "targetNamespace") }} -n {{ .targetNamespace }} {{ end }} {{ $resourceAPIGroup }} {{ .resourceName }} --timeout=60s || exit 1 fi fi echo "Cleanup Job finished" - restartPolicy: Never {{- end }} {{- end }} \ No newline at end of file diff --git a/charts/orchestrator/templates/_helpers.tpl b/charts/orchestrator/templates/_helpers.tpl index 47b4d733..17091918 100644 --- a/charts/orchestrator/templates/_helpers.tpl +++ b/charts/orchestrator/templates/_helpers.tpl @@ -52,7 +52,7 @@ {{- define "install-tekton-task" -}} - {{- if and (.Values.tekton.enabled) (ne .Values.rhdhOperator.secretRef.k8s.clusterToken "") (.Capabilities.APIVersions.Has "tekton.dev/v1/Task") }} + {{- if and (and (and .Values.tekton.enabled .Values.argocd.enabled) (ne .Values.rhdhOperator.secretRef.k8s.clusterToken "")) (.Capabilities.APIVersions.Has "tekton.dev/v1/Task") }} {{- "true" -}} {{- else }} {{- "false" -}} @@ -60,7 +60,7 @@ {{- end -}} {{- define "install-tekton-pipeline" -}} - {{- if and (.Values.tekton.enabled) (ne .Values.rhdhOperator.secretRef.k8s.clusterToken "") (.Capabilities.APIVersions.Has "tekton.dev/v1/Pipeline") }} + {{- if and (and (and .Values.tekton.enabled .Values.argocd.enabled) (ne .Values.rhdhOperator.secretRef.k8s.clusterToken "")) (.Capabilities.APIVersions.Has "tekton.dev/v1/Pipeline") }} {{- "true" -}} {{- else }} {{- "false" -}} @@ -84,24 +84,23 @@ {{- else -}} {{- $ns:= "" }} {{- $list:= lookup "v1" "Namespace" "" "" -}} - {{- if gt 0 (len (dig "items" (dict "" "") $list ) )}} - {{- range (dig "items" (dict "" "") $list) }} - {{- $labels:= dig "metadata" "labels" (dict "" "" ) . -}} - {{- if (hasKey $labels $matchingLabel ) }} - {{- if not $ns }} - {{- $ns = dig "metadata" "name" "" . -}} - {{- else -}} - {{- fail (printf "More than one namespace found with label %s: %s and %s" $matchingLabel $ns (dig "metadata" "name" "" .) )}} - {{- end }} - {{- end -}} + {{- if eq 0 (len (dig "items" (dict "" "") $list ) )}} + {{- fail (printf "No namespaces found: %d" (len (dig "items" (dict "" "") $list)) ) }} + {{- end -}} + {{- range (dig "items" (dict "" "") $list) }} + {{- $labels:= dig "metadata" "labels" (dict "" "" ) . -}} + {{- if (hasKey $labels $matchingLabel ) }} + {{- if not $ns }} + {{- $ns = dig "metadata" "name" "" . -}} + {{- else -}} + {{- fail (printf "More than one namespace found with label %s: %s and %s" $matchingLabel $ns (dig "metadata" "name" "" .) )}} + {{- end }} {{- end -}} - {{- if not $ns -}} - {{- fail (printf "No namespace found with label '%s'. Please follow the installation instructions to properly configure the environment" $matchingLabel) -}} - {{- end }} - {{- $ns }} - {{- else -}} - {{- fail "No namespaces found" }} {{- end -}} + {{- if not $ns -}} + {{- fail (printf "No namespace found with label '%s'. Please follow the installation instructions to properly configure the environment" $matchingLabel) -}} + {{- end }} + {{- $ns }} {{- end -}} {{- end -}} @@ -121,4 +120,4 @@ {{- end -}} {{- .argoCDNamespace -}} {{- end -}} -{{- end -}}s \ No newline at end of file +{{- end -}} \ No newline at end of file diff --git a/charts/orchestrator/templates/argocd-project.yaml b/charts/orchestrator/templates/argocd-project.yaml index 61bfafb6..3236d9b3 100644 --- a/charts/orchestrator/templates/argocd-project.yaml +++ b/charts/orchestrator/templates/argocd-project.yaml @@ -1,10 +1,9 @@ {{- if eq "true" (include "install-argocd-project" .) }} -{{- $gitopsNamespace := include "get-argocd-namespace" . }} apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: orchestrator-gitops - namespace: {{ $gitopsNamespace }} + namespace: {{ include "get-argocd-namespace" . }} spec: destinations: - name: '*' diff --git a/charts/orchestrator/templates/openshift-serverless.yaml b/charts/orchestrator/templates/openshift-serverless.yaml index ab9c846c..373db358 100644 --- a/charts/orchestrator/templates/openshift-serverless.yaml +++ b/charts/orchestrator/templates/openshift-serverless.yaml @@ -27,7 +27,6 @@ metadata: spec: Registry: {{- end }} - #### Openshift Serverless Manifests {{- if .Values.serverlessOperator.enabled }} {{- $unmanagedNamespaceExists := include "unmanaged-resource-exists" (list "v1" "Namespace" "" .Values.serverlessOperator.subscription.namespace .Release.Name .Capabilities.APIVersions) }} @@ -45,7 +44,6 @@ metadata: namespace: {{ .Values.serverlessOperator.subscription.namespace }} spec: {} {{- end }} - {{- $unmanagedSubscriptionExists := include "unmanaged-resource-exists" (list "operators.coreos.com/v1alpha1" "Subscription" .Values.serverlessOperator.subscription.namespace "serverless-operator" .Release.Name .Capabilities.APIVersions ) }} {{- if eq $unmanagedSubscriptionExists "false" }} --- @@ -61,7 +59,6 @@ spec: source: redhat-operators sourceNamespace: openshift-marketplace {{- end }} - {{- $unmanagedNamespaceExists := include "unmanaged-resource-exists" (list "v1" "Namespace" "" "knative-serving" .Release.Name .Capabilities.APIVersions) }} {{- if eq $unmanagedNamespaceExists "false" }} --- @@ -70,7 +67,6 @@ kind: Namespace metadata: name: knative-serving {{- end }} - {{- $unmanagedNamespaceExists := include "unmanaged-resource-exists" (list "v1" "Namespace" "" "knative-eventing" .Release.Name .Capabilities.APIVersions) }} {{- if eq $unmanagedNamespaceExists "false" }} --- @@ -80,7 +76,6 @@ metadata: name: knative-eventing {{- end }} {{- end }} - {{- $unmanagedKnativeEventingExists := include "unmanaged-resource-exists" (list "operator.knative.dev/v1beta1" "KnativeEventing" "knative-eventing" "knative-eventing" .Release.Name .Capabilities.APIVersions) }} {{- if eq $unmanagedKnativeEventingExists "false" }} {{- include "manage-cr-lifecycle-on-action" (dict "release" .Release "apiGroup" "operator.knative.dev" "groupVersion" "v1beta1" "kind" "KnativeEventing" "kinds" "knativeeventings" "targetNamespace" "knative-eventing" "resourceName" "knative-eventing" "isEnabled" .Values.serverlessOperator.enabled "hasCRDInstalled" (.Capabilities.APIVersions.Has "operator.knative.dev/v1beta1/KnativeEventing") "manifest" (include "knativeEventing-manifest" . | b64enc )) }} diff --git a/charts/orchestrator/templates/rhdh-operator.yaml b/charts/orchestrator/templates/rhdh-operator.yaml index 36f7ae98..1865103b 100644 --- a/charts/orchestrator/templates/rhdh-operator.yaml +++ b/charts/orchestrator/templates/rhdh-operator.yaml @@ -328,8 +328,8 @@ data: target: https://github.com/parodos-dev/workflow-software-templates/blob/main/scaffolder-templates/basic-workflow/template.yaml - type: url target: https://github.com/parodos-dev/workflow-software-templates/blob/main/scaffolder-templates/complex-assessment-workflow/template.yaml - {{- $unmanagedNamespaceExists := include "unmanaged-resource-exists" (list "rhdh.redhat.com/v1alpha1" "Backstage" .Values.rhdhOperator.subscription.namespace "backstage" .Release.Name .Capabilities.APIVersions ) }} - {{- if eq $unmanagedNamespaceExists "false" }} - {{- include "manage-cr-lifecycle-on-action" (dict "release" .Release "apiGroup" "rhdh.redhat.com" "groupVersion" "v1alpha1" "kind" "Backstage" "kinds" "backstages" "targetNamespace" .Values.rhdhOperator.subscription.namespace "resourceName" "backstage" "isEnabled" .Values.rhdhOperator.enabled "hasCRDInstalled" (.Capabilities.APIVersions.Has "rhdh.redhat.com/v1alpha1/Backstage") "manifest" (include "backstage-manifest" . | b64enc )) }} - {{- end }} +{{- end }} +{{- $unmanagedNamespaceExists := include "unmanaged-resource-exists" (list "rhdh.redhat.com/v1alpha1" "Backstage" .Values.rhdhOperator.subscription.namespace "backstage" .Release.Name .Capabilities.APIVersions ) }} +{{- if eq $unmanagedNamespaceExists "false" }} + {{- include "manage-cr-lifecycle-on-action" (dict "release" .Release "apiGroup" "rhdh.redhat.com" "groupVersion" "v1alpha1" "kind" "Backstage" "kinds" "backstages" "targetNamespace" .Values.rhdhOperator.subscription.namespace "resourceName" "backstage" "isEnabled" .Values.rhdhOperator.enabled "hasCRDInstalled" (.Capabilities.APIVersions.Has "rhdh.redhat.com/v1alpha1/Backstage") "manifest" (include "backstage-manifest" . | b64enc )) }} {{- end }} diff --git a/charts/orchestrator/templates/tekton-pipeline.yaml b/charts/orchestrator/templates/tekton-pipeline.yaml index 941509b0..09ecd8a1 100644 --- a/charts/orchestrator/templates/tekton-pipeline.yaml +++ b/charts/orchestrator/templates/tekton-pipeline.yaml @@ -1,9 +1,10 @@ {{- if eq "true" (include "install-tekton-pipeline" .) }} + {{- $gitopsNamespace := include "get-argocd-namespace" . }} apiVersion: tekton.dev/v1 kind: Pipeline metadata: name: workflow-deployment - namespace: {{ .Values.argocd.namespace }} + namespace: {{ $gitopsNamespace }} spec: description: | This pipeline clones a git repo, builds a Docker image with Kaniko and @@ -115,7 +116,7 @@ spec: runAfter: ["flatten-workflow"] taskRef: name: buildah - kind: ClusterTask + kind: ClusterTask workspaces: - name: source workspace: workflow-source diff --git a/charts/orchestrator/templates/tekton-tasks.yaml b/charts/orchestrator/templates/tekton-tasks.yaml index 09e7c55b..4d5a4f0a 100644 --- a/charts/orchestrator/templates/tekton-tasks.yaml +++ b/charts/orchestrator/templates/tekton-tasks.yaml @@ -1,10 +1,11 @@ {{- if eq "true" (include "install-tekton-task" .) }} + {{- $gitopsNamespace := include "get-argocd-namespace" . }} # From https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-cli/0.4/git-cli.yaml apiVersion: tekton.dev/v1 kind: Task metadata: name: git-cli - namespace: {{ .Values.argocd.namespace }} + namespace: {{ $gitopsNamespace }} labels: app.kubernetes.io/version: "0.4" annotations: @@ -158,7 +159,7 @@ apiVersion: tekton.dev/v1 kind: Task metadata: name: flattener - namespace: {{ .Values.argocd.namespace }} + namespace: {{ $gitopsNamespace }} spec: workspaces: - name: workflow-source @@ -194,7 +195,7 @@ apiVersion: tekton.dev/v1 kind: Task metadata: name: build-manifests - namespace: {{ .Values.argocd.namespace }} + namespace: {{ $gitopsNamespace }} spec: workspaces: - name: workflow-source @@ -216,7 +217,7 @@ apiVersion: tekton.dev/v1 kind: Task metadata: name: build-gitops - namespace: {{ .Values.argocd.namespace }} + namespace: {{ $gitopsNamespace }} spec: workspaces: - name: workflow-source diff --git a/charts/orchestrator/values.yaml b/charts/orchestrator/values.yaml index b9291e20..c3bb900b 100644 --- a/charts/orchestrator/values.yaml +++ b/charts/orchestrator/values.yaml @@ -25,8 +25,8 @@ rhdhOperator: clientId: GITHUB_CLIENT_ID # Key in the secret with name defined in the 'name' field that contains the value of the client ID that you generated on GitHub, for GitHub authentication (requires GitHub App). Defaults to 'GITHUB_CLIENT_ID', empty for not available. clientSecret: GITHUB_CLIENT_SECRET # Key in the secret with name defined in the 'name' field that contains the value of the client secret tied to the generated client ID. Defaults to 'GITHUB_CLIENT_SECRET', empty for not available. k8s: # Kubernetes specific configuration fields that are injected to the backstage instance to allow the plugin to communicate with the Kubernetes API Server. - clusterToken: K8S_CLUSTER_URL # Key in the secret with name defined in the 'name' field that contains the value of the Kubernetes API bearer token used for authentication. Defaults to 'K8S_CLUSTER_URL', empty for not available. - clusterUrl: K8S_CLUSTER_TOKEN # Key in the secret with name defined in the 'name' field that contains the value of the API URL of the kubernetes cluster. Defaults to 'K8S_CLUSTER_TOKEN', empty for not available. + clusterToken: K8S_CLUSTER_TOKEN # Key in the secret with name defined in the 'name' field that contains the value of the API URL of the kubernetes cluster. Defaults to 'K8S_CLUSTER_TOKEN', empty for not available. + clusterUrl: K8S_CLUSTER_URL # Key in the secret with name defined in the 'name' field that contains the value of the Kubernetes API bearer token used for authentication. Defaults to 'K8S_CLUSTER_URL', empty for not available. argocd: # ArgoCD specific configuration fields that are injected to the backstage instance to allow the plugin to communicate with ArgoCD. Note that ArgoCD must be deployed beforehand and the argocd.enabled field must be set to true as well. url: ARGOCD_URL # Key in the secret with name defined in the 'name' field that contains the value of the URL of the ArgoCD API server. Defaults to 'ARGOCD_URL', empty for not available. username: ARGOCD_USERNAME # Key in the secret with name defined in the 'name' field that contains the value of the username to login to ArgoCD. Defaults to 'ARGOCD_USERNAME', empty for not available.