Merge Generator

Merge Generator

Merge generator는 기본(base, 첫 번째) generator가 만든 파라미터와 그 이후 generator들이 만든 일치하는 파라미터 집합을 결합해요. 일치(matching)는 구성된 merge keys의 값이 같을 때 성립하며, 일치하지 않는 파라미터 집합은 버려져요. 파라미터 집합의 일부만 덮어쓰기(override)해야 할 때 Merge generator가 적합해요.

출처: 문서

본문

Merge generator는 기본(첫 번째) generator가 만든 파라미터를 이후 generator들이 만든 일치하는 파라미터 집합과 결합해요. 일치하는 파라미터 집합은 구성된 merge keys에 대해 같은 값을 가져요. 일치하지 않는 파라미터 집합은 버려져요. 덮어쓰기 우선순위는 아래에서 위로(bottom-to-top)예요. generator 3이 만든 일치 파라미터 집합의 값이 generator 2가 만든 대응 파라미터 집합의 값보다 우선해요.

Merge generator는 파라미터 집합의 일부만 덮어쓰기(override)가 필요할 때 적합해요.

예시: 기본 Cluster generator + override Cluster generator + List generator

예를 들어 클러스터 두 개가 있다고 상상해 봐요.

  • staging 클러스터(https://1.2.3.4)
  • production 클러스터(https://2.4.6.8)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-git
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    # merge 'parent' generator
    - merge:
        mergeKeys:
          - server
        generators:
          - clusters:
              values:
                kafka: 'true'
                redis: 'false'
          # For clusters with a specific label, enable Kafka.
          - clusters:
              selector:
                matchLabels:
                  use-kafka: 'false'
              values:
                kafka: 'false'
          # For a specific cluster, enable Redis.
          - list:
              elements: 
                - server: https://2.4.6.8
                  values.redis: 'true'
  template:
    metadata:
      name: '{{.name}}'
    spec:
      project: '{{index .metadata.labels "environment"}}'
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        path: app
        helm:
          parameters:
            - name: kafka
              value: '{{.values.kafka}}'
            - name: redis
              value: '{{.values.redis}}'
      destination:
        server: '{{.server}}'
        namespace: default

기본 Cluster generator는 Argo CD에 정의된 클러스터 집합을 스캔해 staging과 production 클러스터 시크릿을 찾고, 두 개의 파라미터 집합을 만들어요.

- name: staging
  server: https://1.2.3.4
  values.kafka: 'true'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'false'

override Cluster generator는 Argo CD에 정의된 클러스터 집합을 스캔해 (필수 라벨을 가진) staging 클러스터 시크릿을 찾고 다음 파라미터를 만들어요.

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'

기본 generator의 파라미터와 병합되면 staging 클러스터의 values.kafka 값이 'false'로 설정돼요.

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'false'

마지막으로 List generator가 단일 파라미터 집합을 생성해요.

- server: https://2.4.6.8
  values.redis: 'true'

업데이트된 기본 파라미터와 병합되면 production 클러스터의 values.redis 값이 'true'로 설정돼요. 이것이 merge generator의 최종 출력이에요.

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'true'

예시: merge에서 값 보간(value interpolation) 사용

일부 generator는 추가 values와 생성 변수에서 선택된 값으로의 보간을 지원해요. 이것은 merge generator에게 서로 다른 generator를 결합할 때 어떤 생성 변수를 사용할지 알려주는 데 쓸 수 있어요.

다음 예시는 클러스터 라벨과 브랜치 이름으로 발견된 클러스터와 git 저장소를 결합해요.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-git
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    # merge 'parent' generator:
    # Use the selector set by both child generators to combine them.
    - merge:
        mergeKeys:
          # Note that this would not work with goTemplate enabled,
          # nested merge keys are not supported there.
          - values.selector
        generators:
          # Assuming, all configured clusters have a label for their location:
          # Set the selector to this location.
          - clusters:
              values:
                selector: '{{index .metadata.labels "location"}}'
          # The git repo may have different directories which correspond to the
          # cluster locations, using these as a selector.
          - git:
              repoURL: https://github.com/argoproj/argocd-example-apps/
              revision: HEAD
              directories:
              - path: '*'
              values:
                selector: '{{.path.path}}'
  template:
    metadata:
      name: '{{.name}}'
    spec:
      project: '{{index .metadata.labels "environment"}}'
      source:
        repoURL: https://github.com/argoproj/argocd-example-apps/
        # The cluster values field for each generator will be substituted here:
        targetRevision: HEAD
        path: '{{.path.path}}'
      destination:
        server: '{{.server}}'
        namespace: default

metadata.labels.location=Germany 라벨을 가진 germany01이라는 클러스터와 Germany라는 디렉토리를 포함한 git 저장소가 있다고 가정하면, 다음과 같은 값으로 결합될 수 있어요.

  # From the cluster generator
- name: germany01
  server: https://1.2.3.4
  # From the git generator
  path: Germany
  # Combining selector with the merge generator
  values.selector: 'Germany'
  # More values from cluster & git generator
  # […]

제한 사항 (Restrictions)

  1. 각 배열 항목에는 단일 generator만 지정해야 해요. 다음은 유효하지 않아요.

    - merge:
        generators:
        - list: # (...)
          git: # (...)
    
    • 이것은 Kubernetes API 검증에서는 수용되겠지만, 컨트롤러는 생성 시 오류를 보고할 거예요. 각 generator는 위 예시들처럼 별도의 배열 요소에 지정해야 해요.
  2. Merge generator는 하위 generator에 지정된 template overrides를 지원하지 않아요. 이 template은 처리되지 않아요.

    - merge:
        generators:
          - list:
              elements:
                - # (...)
              template: { } # Not processed
    
  3. 결합형 generator(Matrix 또는 Merge)는 한 번만 중첩할 수 있어요. 예를 들어 다음은 동작하지 않아요.

    - merge:
        generators:
          - merge:
              generators:
                - merge:  # This third level is invalid.
                    generators:
                      - list:
                          elements:
                            - # (...)
    
  4. goTemplate: true를 사용하면서 중첩된 값에 병합하는 것은 현재 지원되지 않아요. 다음은 동작하지 않아요.

    spec:
      goTemplate: true
      generators:
      - merge:
          mergeKeys:
            - values.merge
    

더 알아보기 (Learn more)