Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bitnami/argo-cd] Add native support for ConfigManagementPlugins #27628

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

maxnitze
Copy link
Contributor

@maxnitze maxnitze commented Jul 2, 2024

Description of the change

Adding support for ArgoCD Config Management Plugins (CMP) to the chart.

Argo CD's "native" config management tools are Helm, Jsonnet, and Kustomize. If you want to use a different config management tools, or if Argo CD's native tool support does not include a feature you need, you might need to turn to a Config Management Plugin (CMP).

Adding those plugins creates a bit of overhead, as there are some volumes that need to be shared between the repo server and the sidecar container of the plugin and the sidecar configuration in general. This is automatically added when the plugins are enabled.

Benefits

ConfigManagementPlugins can be enabled directly from the chart.

Example with the argocd-vault-plugin

Here's an example of how I would be using it for a CMP that adds support for the argocd-vault-plugin.

repoServer:
  extraVolumes:
    - name: vault-configuration
      secret:
        secretName: argo-cd-vault-configuration

  configManagementPlugins:
    enabled: true
    additionalBinaries:
      - name: argocd-vault-plugin
        url: https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v1.18.1/argocd-vault-plugin_1.18.1_linux_amd64
    plugins:
      - name: avp-helm
        spec:
          init:
            command:
              - /bin/sh
              - -c
              - |
                #!/usr/bin/env bash
                set -Eeuo pipefail
                
                # add all repositories from dependencies of this chart
                for REPO_URL in $(helm dependency list | tail -n+2 | tr -s '[:space:]' | cut -f3)
                do
                  # skip entries that reference local charts
                  if [[ "${REPO_URL}" == file://* ]]; then continue; fi
                  helm repo add $(echo -n "${REPO_URL}" | base64 -w0) "${REPO_URL}"
                done
                
                # finally download the charts dependencies
                helm dependency build
          generate:
            command:
              - /bin/sh
              - -c
              - |
                #!/usr/bin/env bash
                set -Eeuo pipefail
                
                # do some magic with the parameters
                # see https://github.com/argoproj-labs/argocd-vault-plugin/issues/566 for an example
                
                helm template ${HELM_RELEASE_NAME} \
                  --namespace ${ARGOCD_APP_NAMESPACE} \
                  ${HELM_VALUE_FILES} \
                  ${HELM_PARAMETERS} \
                  ${HELM_EXTRA_PARAMETERS} \
                  ./ |
                argocd-vault-plugin generate - -c /run/secrets/vault-configuration/config.yaml
          allowConcurrency: true
          lockRepo: false
        sidecar:
          image:
            repository: alpine/helm
            tag: 3.12.3
          extraEnvVars:
            # root filesystem is read-only, so we need to move the Helm home folders to /tmp
            - name: HELM_CACHE_HOME
              value: /tmp/helm/cache
            - name: HELM_CONFIG_HOME
              value: /tmp/helm/config
            - name: HELM_DATA_HOME
              value: /tmp/helm/data
          extraVolumeMounts:
            - mountPath: /run/secrets/vault-configuration/config.yaml
              name: vault-configuration
              subPath: config.yaml

Possible drawbacks

The change tries to make everything as much configurable as possible. So no drawbacks there (hopefully).

The change in general is opt-in. So no undesired changes to existing installations.

Applicable issues

None

Additional information

argocd.tplvalues.merge-with-precedence Helper

I introduced a new helper for merging values from a list with precedence to later entries.

This was necessary, because the helper common.tplvalues.merge has one major "flaw", that I needed fixed here:

context1:
  enabled: true
  name: 1001
  isRunning: true
context2:
  enabled: false
  name: 1234
  isRunning: false

When I merge these two with include "common.tplvalues.merge" (dict "values" (list .context1 .context2) "context" $), the result is

mergedContext:
  enabled: true
  name: 1234
  isRunning: true

I don't know if this is a bug or a feature (the comment of the helper says, that "precedence is consistent with http://masterminds.github.io/sprig/dicts.html#merge-mustmerge").

Since I was merging container security contexts here, I wanted to be give the option to deactivate the readOnlyRootFilesystem, for example. Or disable the context completely.

The result when using the new helper include "argocd.tplvalues.merge-with-precedence" (dict "values" (list .context1 .context2) "context" $) is

mergedContext:
  enabled: false
  name: 1234
  isRunning: false

Checklist

  • Chart version bumped in Chart.yaml according to semver. This is not necessary when the changes only affect README.md files.
  • Variables are documented in the values.yaml and added to the README.md using readme-generator-for-helm
  • Title of the pull request follows this pattern [bitnami/<name_of_the_chart>] Descriptive title
  • All commits signed off and in agreement of Developer Certificate of Origin (DCO)

@github-actions github-actions bot added argo-cd triage Triage is needed labels Jul 2, 2024
@github-actions github-actions bot requested a review from carrodher July 2, 2024 11:07
@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch from 1d02ec8 to 8e0232a Compare July 2, 2024 11:10
@carrodher carrodher added verify Execute verification workflow for these changes in-progress labels Jul 2, 2024
@github-actions github-actions bot removed the triage Triage is needed label Jul 2, 2024
@github-actions github-actions bot removed the request for review from carrodher July 2, 2024 19:19
@github-actions github-actions bot requested a review from andresbono July 2, 2024 19:19
@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch 5 times, most recently from 255d610 to 3801362 Compare July 9, 2024 09:54
@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch from 08f19c9 to ad57930 Compare July 15, 2024 14:24
@maxnitze
Copy link
Contributor Author

Not sure why the VIB Verify check failed here. But it also failed for other PRs. Maybe somethings wrong with the action?

@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch from a74cb4f to 349c29d Compare July 16, 2024 12:42
Copy link
Member

@andresbono andresbono left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for your contribution, this could be a great addition! I left some initial questions. Let's discuss them before we go more in depth!

Comment on lines +3158 to +3161
## @param repoServer.configManagementPlugins.enabled Whether the config management plugins are enabled or not.
enabled: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new value repoServer.configManagementPlugins.enabled actually needed? Wouldn't it be enough to check if repoServer.configManagementPlugins.plugins has elements or not?

  • If it has elements, then we consider the feature activated
  • Otherwise, deactivated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, yeah. This is the pattern we use for most features though, right? I also like the fact, that for debugging purposes you can just disable it here without having to delete the whole plugins config.

## - name: my-custom-binary
## url: https://www.example.com/my-custom-binary-1.2.3
## customScript: ""
additionalBinaries: []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we achieve the same by using repoServer.initContainers? And it gives you more flexibility... In addition to that, I would expect that users also customize their container images to include any required binaries baked in the image instead of having to download the binaries every time at runtime. Does it make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. In the end having the binaries here will only fill an init container. You can still use your own init container or bake your binaries into your custom image. You just have to make sure, that the binaries are on the path in the sidecar container, that runs your plugin.

The whole point of the change was to get rid of the boilerplate and having a simple way of configuring a CMP. That why I included this. But as stated, this is fully optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I was thinking about it: Maybe we can skip the "customScript" part and recommend to use an own init container or custom image in that case. But for the easy cases, where the binary can just be downloaded from a given URL, I would prefre to keep the functionality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, at the very least, we should skip the customScript part. Will you update the PR? Once we have that removed, let's see if it makes sense to keep simplifying the implementation. Thanks!

@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch 2 times, most recently from 8dcbbb4 to 7f95571 Compare July 23, 2024 15:57
@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch from 09b9eae to 6107d31 Compare July 31, 2024 14:17
@maxnitze
Copy link
Contributor Author

maxnitze commented Jul 31, 2024

Updated the chart and removed the custom script option of the additional binaries.

@andresbono
Copy link
Member

@maxnitze, thank you for addressing this. Let me take a look at the changes to get back to you. No worries about the conflicts, I'll take care of resolving them.

name: cmp-additional-binaries
{{- if .Values.repoServer.configManagementPlugins.additionalBinaries }}
- name: download-additional-binaries
image: {{ include "common.images.image" (dict "imageRoot" (dict "repository" "curlimages/curl" "tag" "latest") "global" .Values.global) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any container image should be maintained by Bitnami and configured in a standard way from values.yaml. You could use bitnami/os-shell. Look at the volumePermissions.image value to follow a similar pattern.

Do you have any concerns with that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues at all! I remember thinking about this when I added the init-container. I think I just forgot about it. Anyway, added it now!

@maxnitze maxnitze force-pushed the feature/argocd-custom-management-plugin-support branch from 6ea59ed to ff3d0f6 Compare August 20, 2024 14:03
bitnami-bot and others added 3 commits August 20, 2024 14:07
Signed-off-by: Bitnami Containers <[email protected]>
Signed-off-by: Bitnami Containers <[email protected]>
Copy link
Member

@andresbono andresbono left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I just added some comments to the PR. Could you please check? Thank you!

@@ -191,6 +191,24 @@ Create the name of the service account to use for Dex
{{- end -}}
{{- end -}}

{{/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what is the value of having this helper function here in argo-cd. It looks like a generic function unrelated to argo-cd itself.

This should go in the common library, although I would try to avoid adding more complexity and try to avoid the usage of this helper if possible.

- /opt/bitnami/argo-cd/bin/argocd
- /additional-binaries/argocd-cmp-server
{{- if .Values.repoServer.containerSecurityContext.enabled }}
securityContext: {{- omit .Values.repoServer.containerSecurityContext "enabled" | toYaml | nindent 12 }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
securityContext: {{- omit .Values.repoServer.containerSecurityContext "enabled" | toYaml | nindent 12 }}
securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.repoServer.containerSecurityContext "context" $) | nindent 12 }}

{{- with .Values.repoServer.configManagementPlugins.additionalBinaries }}
{{- if .binaries }}
- name: download-additional-binaries
image: {{ include "common.images.image" (dict "imageRoot" .image "global" $.Values.global) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go into its own helper function (see examples for the other images):

{{/*
Return the proper CMP binary downloader image name
*/}}
{{- define "argocd.repoServer.configManagementPlugins.additionalBinaries.image" -}}
{{- include "common.images.image" ( dict "imageRoot" .Values.repoServer.configManagementPlugins.additionalBinaries.image "global" .Values.global ) -}}
{{- end -}}

and be called like:

Suggested change
image: {{ include "common.images.image" (dict "imageRoot" .image "global" $.Values.global) }}
image: {{ include "argocd.repoServer.configManagementPlugins.additionalBinaries.image" . }}

imagePullPolicy: {{ .image.pullPolicy }}
command:
- sh
- -c
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we pass the -ec flags to detect errors?

Comment on lines +323 to +324
- name: {{ $plugin.name }}
image: {{ include "common.images.image" (dict "imageRoot" $plugin.sidecar.image "global" $.Values.global) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to simplify all this and let users decide what will be the sidecar preferred structure. It simplify our maintenance at the same time it allows total flexibility for users.

It would be the same approach that we follow in .Values.repoServer.sidecars for example.

{{- end }}
{{- if $plugin.sidecar.resources }}
resources: {{- toYaml $plugin.sidecar.resources | nindent 12 }}
{{- else if and $plugin.sidecar.resourcePreset (ne $plugin.sidecar.resourcesPreset "none") }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo here, but in any case, refer to my previous comment about simplifying all this code and allow users to set their sidecars config explicitly.

Suggested change
{{- else if and $plugin.sidecar.resourcePreset (ne $plugin.sidecar.resourcesPreset "none") }}
{{- else if and $plugin.sidecar.resourcesPreset (ne $plugin.sidecar.resourcesPreset "none") }}

## pullSecrets:
## - myRegistryKeySecretName
##
pullSecrets: [ ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this image be added to argocd.imagePullSecrets?

Copy link

This Pull Request has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thank you for your contribution.

@github-actions github-actions bot added the stale 15 days without activity label Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
argo-cd in-progress stale 15 days without activity verify Execute verification workflow for these changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants