apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  annotations:
    tekton.dev/displayName: create-external-secret
    tekton.dev/pipelines.minVersion: 0.17.0
    tekton.dev/tags: cli
  name: create-external-secret
  labels:
    app.kubernetes.io/version: '0.1'
spec:
  description: >-
    `create-external-secret` creates an ExternalSecrets in a provided NAMESPACE given a KEY_ID. This task assumes that a ClusterSecretStore is already created.
  params:
    - name: CLUSTER_SECRET_STORE_NAME
      type: string
      description: ClusterSecretStore name
    - name: TARGET_SECRET_NAME
      type: string
      description: Kubernetes secret name to be created
    - name: TARGET_SECRET_NAMESPACE
      type: string
      description: Kubernetes namespace to put secret in
    - name: SECRET_DATA
      type: string
      description: |-
        ExternalSecrets data, expressed as an array with elements `- key: username\n  id: 1234`, e.g.:

        SECRET_DATA: |-
          - key: username
            id: 1234
          - key: password
            id: 5789
  steps:
    - env:
        - name: HOME
          value: /tekton/home
      image: >-
        quay.io/congxdev/ibm-pak-ubi:latest
      name: oc
      resources: {}
      script: |
        #!/usr/bin/env bash

        mkdir ~/tmp && cd ~/tmp

        [[ "$(workspaces.manifest-dir.bound)" == "true" ]] && \
        cd $(workspaces.manifest-dir.path)

        [[ "$(workspaces.kubeconfig-dir.bound)" == "true" ]] && \
        [[ -f $(workspaces.kubeconfig-dir.path)/kubeconfig ]] && \
        export KUBECONFIG=$(workspaces.kubeconfig-dir.path)/kubeconfig

        set -e

        cat <<EOF > input.yaml
        $(params.SECRET_DATA)
        EOF

        yq '.[] | [{"secretKey": .key, "remoteRef": { "key": .id }}]' input.yaml > spec_data_field.yaml
        yq -i '. | {"spec": {"data": . }}' spec_data_field.yaml
        
        yq '.[] | {(.key): "{{ ." + .key + " }}"}' input.yaml > target_template_data_field.yaml
        yq -i '. | {"spec": {"target": {"template": {"data": . }}}}' target_template_data_field.yaml

        cat spec_data_field.yaml
        cat target_template_data_field.yaml

        cat <<EOF > external_secret.yaml
        ---
        apiVersion: external-secrets.io/v1beta1
        kind: ExternalSecret
        metadata:
          name: $(params.TARGET_SECRET_NAME)
          namespace: $(params.TARGET_SECRET_NAMESPACE)
        spec: 
          data: []
          refreshInterval: 1h0m0s
          secretStoreRef: 
            name: $(params.CLUSTER_SECRET_STORE_NAME)
            kind: ClusterSecretStore
          target:
            name: $(params.TARGET_SECRET_NAME)
            creationPolicy: Owner
            template:
              engineVersion: v2
              type: Opaque
              data: []
        EOF

        cat external_secret.yaml
        yq -i ".spec.data = \"$spec_data_field\"" -i external_secret.yaml
        yq -i ".spec.target.template.data = \"$target_template_data_field\"" -i external_secret.yaml

        yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1) * select(fileIndex == 2)' external_secret.yaml spec_data_field.yaml target_template_data_field.yaml

        cat external_secret.yaml

        oc apply -f external_secret.yaml

        while true; do
          oc get externalsecret.external-secrets.io/$(params.TARGET_SECRET_NAME) -n $(params.TARGET_SECRET_NAMESPACE) -o yaml > obj.yaml

          export num_conditions=$(yq eval '.status.conditions | length' obj.yaml)
          export num_ready_conditions=$(yq eval '.status.conditions | map(select(.status == "True" and .type == "Ready")) | length' obj.yaml)

          # Check if the health status is "Healthy." If so, exit the loop with exit code 0.
          if [ "$num_ready_conditions" -eq "$num_conditions" ]; then
            echo $(yq eval '.status.conditions | .[].message' obj.yaml)
            exit 0
          fi

          echo "ExternalSecret is not healthy yet."
          echo $(yq eval '.status.conditions | .[].message' obj.yaml)
          # Add a delay (e.g., 5 seconds) before the next iteration (optional, adjust as needed)
          sleep 5
        done
      securityContext:
        runAsNonRoot: true
        runAsUser: 65532
  results:
    - name: output
      description: The output of the task
  workspaces:
    - description: >-
        The workspace which contains kubernetes manifests which we want to apply
        on the cluster.
      name: manifest-dir
      optional: true
    - description: >-
        The workspace which contains the the kubeconfig file if in case we want
        to run the oc command on another cluster.
      name: kubeconfig-dir
      optional: true
