kcl-lang / kcl-lang.io

KCL Website and Documentation Repo: https://kcl-lang.io
https://kcl-lang.github.io
Apache License 2.0
15 stars 34 forks source link

[Enhancement?] GitOps with KCL and ArgoCD #490

Open eminaktas opened 2 days ago

eminaktas commented 2 days ago

Enhancement

Hi, after working on GitOps with KCL and ArgoCD for a while I needed to adjust the plugin configuration. Since my plan is to use a single template and output the parameters via multiple configuration yaml files, this way I can have flexibility in my environments. Basically, I wanted to have something like valueFiles in Helm.

This change requires jq to be installed inside the container. I am not an expert on this ArgoCD plugin but we should have a programming way to do this to make it better. However, this change solves what I need.

I would like to get your opinion on this.

apiVersion: v1
kind: ConfigMap
metadata:
  name: kcl-plugin-config
  namespace: argocd
data:
  # Sometimes, the ArgoCD runs the kcl run command twice simultaneously,
  # leading to a race condition in the usage of files inside the
  # KCL_CACHE_PATH and KCL_PKG_PATH directories.
  plugin.yaml: |
    apiVersion: argoproj.io/v1alpha1
    kind: ConfigManagementPlugin
    metadata:
      name: kcl
    spec:
      version: v1.0
      generate:
        command: ["bash", "-c"]
        args:
          - |
            set -o pipefail
            export KCL_CACHE_PATH=/tmp
            export KCL_PKG_PATH=/tmp
            tempfile=$(mktemp)
            cmd="kcl run -q -o $tempfile"

            # Parse ARGOCD_APP_PARAMETERS
            parameters=$(echo $ARGOCD_APP_PARAMETERS | jq -c '.[]')

            # Iterate through parameters and extract values
            for param in $parameters; do
              name=$(echo "$param" | jq -r '.name')

              if [ "$name" = "settings" ]; then
                settings=$(echo "$param" | jq -r '.array[]')
                for setting in $settings; do
                  cmd="$cmd -Y $setting"
                done
              fi

              if [ "$name" = "arguments" ]; then
                arguments=$(echo "$param" | jq -r '.array[]')
                for argument in $arguments; do
                  cmd="$cmd -D $argument"
                done
              fi

              if [ "$name" = "disable_none" ]; then
                disable_none=$(echo "$param" | jq -r '.string')
                if [ "$disable_none" = "true" ]; then
                  cmd="$cmd -n"
                fi
              fi
            done

            # Run the command
            $cmd
            error=$?
            if [ $error -eq 0 ]; then
              cat $tempfile
              rm $tempfile
            fi
            exit $error
      parameters:
        static:
        - name: settings
          title: Specify the command line setting files
          required: false
          itemType: array
          collectionType: array
        - name: arguments
          title: Specify the top-level arguments
          required: false
          itemType: array
          collectionType: array
        - name: disable_none
          title: Disable dumping None values
          required: false
          itemType: string
          collectionType: string
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: custom-app
  namespace: argocd
spec:
  destination:
    namespace: default
    server: https://kubernetes.default.svc
  project: default
  source:
    plugin:
      name: kcl-v1.0
      parameters:
        - name: settings
          array: [kcl.yaml]
        # - name: arguments
        #   array: ["option1=value1", "option2=value2"]
        # - name: disable_none
        #   string: "true"
    # The configuration files are in `values` directory
    path: "example"
    repoURL: https://some-registery.com/custom-app

Also, I had an issue with the kcllang/kcl image that fails. to get the packages from registry. However, I saw this commit to fix the issue.

docker run --rm -it kcllang/kcl kcl mod pull k8s
start to pull oci://ghcr.io/kcl-lang/k8s
failed to select latest version from 'ghcr.io/kcl-lang/k8s'
Get "https://ghcr.io/v2/kcl-lang/k8s/tags/list": tls: failed to verify certificate: x509: certificate signed by unknown authority
Peefy commented 2 days ago

Also, I had an issue with the kcllang/kcl image that fails. to get the packages from registry. However, I saw this commit to fix the issue.

Yes, I've release a new latest kcllang/kcl image to fix the issue.

Peefy commented 2 days ago

https://github.com/kcl-lang/flux-kcl-controller Do you mean to use programming methods like the flux kcl controller instead of writing unmaintainable script plugins to extend ArgoCD?

eminaktas commented 2 days ago

https://github.com/kcl-lang/flux-kcl-controller Do you mean to use programming methods like the flux kcl controller instead of writing unmaintainable script plugins to extend ArgoCD?

Yes, if you think this is a logical way to do it.

I think this way kcl's plugin could support more use cases. For example, using KCLRun can be available in ArgoCD which is supported in flux-kcl-controller.

Peefy commented 2 days ago

Thank you! I think this is worth considering. 👍

cc @zong-zhe