argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
18.04k stars 5.51k forks source link

Support a list of values as string in the generators selectors #20943

Open OpenGuidou opened 3 days ago

OpenGuidou commented 3 days ago

Summary

With the current state of applicationset templating, it's not possible to provide values as a list in a selector matchExpressions values, coming from variables defined in the generator or from another generator.

Motivation

Let's take the example of this applicationset:

spec:
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
          envs:
            - staging
            - prod
      selector:
        matchExpressions:
          - key: env
            operator: In
            values:
              - {{ .envs }}

It's not possible to provide the envs variable in the selector values.

Proposal

I would propose to add a field in the matchExpression, to support a list of values as string:

spec:
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
          envs:
            - staging
            - prod
      selector:
        matchExpressions:
          - key: env
            operator: In
            valuesString: "staging,prod"

This would be a comma-separated list, as a string, that could be filled using templating functions:

spec:
  goTemplate: true
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
          envs:
            - staging
            - prod
      selector:
        matchExpressions:
          - key: env
            operator: In
            valuesString: `{{- join "," .envs }}`
damsien commented 3 days ago

Hello, can I take this issue? 🙂 @OpenGuidou can you confirm that we should have either values or valuesString (both can't be used at the same time).

OpenGuidou commented 3 days ago

Sure, go ahead !

It's Indeed a good idea to check only one is provided

damsien commented 3 days ago

Thanks! /assign

damsien commented 2 days ago

I took a look at the issue. I am not sure that it is a good idea to add the valuesString field since it is redundant. Why not using in this way?

spec:
  goTemplate: true
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
          envs:
            - staging
            - prod
      selector:
        matchExpressions:
          - key: env
            operator: In
            values: [`{{- range $index, $env := .envs }}{{ if $index }}, {{ end }}"{{ $env }}"{{- end }}`]

The thing is we want to be as much close to the native Kubernetes API as possible. The struct for the matchExpressions does not include the valuesString field.

OpenGuidou commented 2 days ago

You would still end up with a list of a single string. The idea would be to extend the metav1 LabelSelector, and convert the valuesString to values before applying the selector