apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: test-hello-world-appset
  namespace: argocd
spec:
  generators:
    # The list generator generates a set of two application which then filter by the key value to only select the env with value staging
    - list:
        elements:
          - cluster: engineering-dev
            url: https://kubernetes.default.svc
            env: staging
          - cluster: engineering-prod
            url: https://kubernetes.default.svc
            env: prod
        # The generator's template field takes precedence over the spec's template fields
        template:
          metadata: {}
          spec:
            project: "default"
            source:
              revision: HEAD
              repoURL: https://github.com/argoproj/argo-cd.git
              # New path value is generated here:
              path: 'applicationset/examples/template-override/{{cluster}}-override'
            destination: {}

      # Selector allows to post-filter all generator.
      selector:
        matchLabels:
          env: staging
          
    # It is also possible to use matchExpressions for more powerful selectors
    - clusters: {}
      selector:
        matchExpressions:
          - key: server
            operator: In
            values:
              - https://kubernetes.default.svc
              - https://some-other-cluster

    # Git generator generates parametes either from directory structure of files within a git repo
    - git:
        repoURL: https://github.com/argoproj/argo-cd.git
        # OPTIONAL: use directory structure of git repo to generate parameters
        directories:
        - path: applicationset/examples/git-generator-directory/excludes/cluster-addons/*
        - path: applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook
          exclude: true # Exclude directory when generating parameters
        # OPTIONAL: generates parameters using the contents of JSON/YAML files found in git repo
        files:
        - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json"
        - path: "applicationset/examples/git-generator-files-discovery/cluster-config/*/dev/config.json"
          exclude: true # Exclude file when generating parameters
        revision: HEAD
        # OPTIONAL: Checks for changes every 60sec (default 3min)
        requeueAfterSeconds: 60
        # The generator's template field takes precedence over the spec's template fields
        template:
        # OPTIONAL: all path-related parameter names will be prefixed with the specified value and a dot separator
        pathParamPrefix: myRepo
        # OPTIONAL: Values contains key/value pairs which are passed directly as parameters to the template
        values:
          cluster: '{{.path.basename}}'


    # to automatically discover repositories within an organization
    - scmProvider:
        # Which protocol to clone using.
        cloneProtocol: ssh
        # The GitHub mode uses the GitHub API to scan an organization in either github.com or GitHub Enterprise
        github:
          # The GitHub organization to scan.
          organization: myorg
          # For GitHub Enterprise:
          api: https://git.example.com/
          # If true, scan every branch of every repository. If false, scan only the default branch. Defaults to false.
          allBranches: true
          # Reference to a Secret containing an access token. (optional)
          tokenRef:
            secretName: github-token
            key: token
          # (optional) use a GitHub App to access the API instead of a PAT.
          appSecretName: gh-app-repo-creds
          #Pass additional key-value pairs via values field
          values:
            name: "{{organization}}-{{repository}}"

        #The GitLab mode uses the GitLab API to scan and organization in either gitlab.com or self-hosted GitLab.  
        gitlab:
        #The Gitea mode uses the Gitea API to scan organizations in your instance
        gitea:
        #Use the Bitbucket Server API (1.0) to scan repos in a project.
        bitbucketServer:
        #Uses the Azure DevOps API to look up eligible repositories 
        azureDevOps:
        # The Bitbucket mode uses the Bitbucket API V2 to scan a workspace in bitbucket.org
        bitbucket:
        #Uses AWS ResourceGroupsTagging and AWS CodeCommit APIs to scan repos across AWS accounts and regionsz
        awsCodeCommit:

        #Filters allow selecting which repositories to generate for. 
        filters:
        # Include any repository starting with "myapp" AND including a Kustomize config AND labeled with "deploy-ok" ...
        - repositoryMatch: ^myapp
          pathsExist: [kubernetes/kustomization.yaml]
          labelMatch: deploy-ok
        # ... OR include any repository starting with "otherapp" AND a Helm folder and doesn't have file disabledrepo.txt.
        - repositoryMatch: ^otherapp
          pathsExist: [helm]
          pathsDoNotExist: [disabledrepo.txt]

    # Cluster-decision-resource-based ApplicationSet generator
    - clusterDecisionResource:
      # ConfigMap with GVK information for the duck type resource
      configMapRef: my-configmap  
      name: quak           # Choose either "name" of the resource or "labelSelector"
      labelSelector:
        matchLabels:       # OPTIONAL
          duck: spotted
        matchExpressions:  # OPTIONAL
        - key: duck
          operator: In
          values:
          - "spotted"
          - "canvasback"   
      # OPTIONAL: Checks for changes every 60sec (default 3min)
      requeueAfterSeconds: 60
  
    # The Pull Request generator uses the API of an SCMaaS provider to automatically discover open pull requests within a repository
    - pullRequest:
        # When using a Pull Request generator, the ApplicationSet controller polls every `requeueAfterSeconds` interval (defaulting to every 30 minutes) to detect changes.
        requeueAfterSeconds: 1800
        # See below for provider specific options.
        # Specify the repository from which to fetch the GitHub Pull requests.
        github:
          # The GitHub organization or user.
          owner: myorg
          # The Github repository
          repo: myrepository
          # For GitHub Enterprise (optional)
          api: https://git.example.com/
          # Reference to a Secret containing an access token. (optional)
          tokenRef:
            secretName: github-token
            key: token
          # (optional) use a GitHub App to access the API instead of a PAT.
          appSecretName: github-app-repo-creds
          # Labels is used to filter the PRs that you want to target. (optional)
          labels:
          - preview

        # Filters allow selecting which pull requests to generate for
        # Include any pull request ending with "argocd". (optional)
        filters:
        - branchMatch: ".*-argocd"

        # Specify the project from which to fetch the GitLab merge requests.
        gitlab:
        # Specify the repository from which to fetch the Gitea Pull requests.
        gitea:
        # Fetch pull requests from a repo hosted on a Bitbucket Server (not the same as Bitbucket Cloud).
        bitbucketServer:
        # Fetch pull requests from a repo hosted on a Bitbucket Cloud.
        bitbucket:
        # Specify the organization, project and repository from which you want to fetch pull requests.
        azuredevops:
        # Fetch pull requests from AWS CodeCommit repositories.
        awsCodeCommit:
   
    # matrix 'parent' generator
    - matrix:
        generators:
        # any of the top-level generators may be used here instead.
  
    # merge 'parent' generator
    # Use the selector set by both child generators to combine them.
    - merge:
        mergeKeys:
          - server
          # Note that this would not work with goTemplate enabled,
          # nested merge keys are not supported there.
          - values.selector
        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'

    # Using a generator plugin without combining it with Matrix or Merge
    # Plugins allow you to provide your own generator
    - plugin:
      # Specify the configMap where the plugin configuration is located.
      configMapRef:
        name: my-plugin
      # You can pass arbitrary parameters to the plugin. `input.parameters` is a map, but values may be any type.
      # These parameters will also be available on the generator's output under the `generator.input.parameters` key.
      input:
        parameters:
          key1: "value1"
          key2: "value2"
          list: ["list", "of", "values"]
          boolean: true
          map:
            key1: "value1"
            key2: "value2"
            key3: "value3"
        # You can also attach arbitrary values to the generator's output under the `values` key. These values will be
        # available in templates under the `values` key.
        values:
          value1: something
        # When using a Plugin generator, the ApplicationSet controller polls every `requeueAfterSeconds` interval (defaulting to every 30 minutes) to detect changes.
        requeueAfterSeconds: 30
                
              
  # Determines whether go templating will be used in the `template` field below.
  goTemplate: true
  # Optional list of go templating options, see https://pkg.go.dev/text/template#Template.Option
  # This is only relevant if `goTemplate` is true
  goTemplateOptions: ["missingkey=error"]

  # These fields are identical to the Application spec.
  # The generator's template field takes precedence over the spec's template fields
  template:
    metadata:
      name: test-hello-world-app
    spec:
      project: my-project
      syncPolicy: 
        automated:
          selfHeal: true    
        syncOptions:
        - CreateNamespace=true  
      # defines from which Git repository to extract the desired Application manifests
      source:
        - chart: '{{.chart}}'
        # developers may customize app details using JSON files from above repo URL
          repoURL: https://github.com/argoproj/argo-cd.git
          targetRevision: HEAD
          # Path within the repository where Kubernetes manifests are located
          path: applicationset/examples/list-generator/guestbook/{{cluster}}
          helm:
            useCredentials: "{{.useCredentials}}"  # This field may NOT be templated, because it is a boolean field
          parameters:
          - name: "image.tag"
            value: "pull-{{head_sha}}"
          - name: "{{.name}}"
            value: "{{.value}}"
          - name: throw-away
            value: "{{end}}"
      destination:
        # Only one of name or server may be specified: if both are specified, an error is returned.
        #  Name of the cluster (within Argo CD) to deploy to
        name: production-cluster # cluster is restricted
        #  API Server URL for the cluster
        server: '{{.url}}'
        # Target namespace in which to deploy the manifests from source 
        namespace: dev-team-one # namespace is restricted

  # This sync policy pertains to the ApplicationSet, not to the Applications it creates.
  syncPolicy:
    # Prevents ApplicationSet controller from modifying or deleting Applications
    applicationsSync: create-only

    # Prevents ApplicationSet controller from deleting Applications. Update is allowed
    # applicationsSync: create-update

    # Prevents ApplicationSet controller from modifying Applications. Delete is allowed.
    # applicationsSync: create-delete

    # Prevent an Application's child resources from being deleted, when the parent Application is deleted
    preserveResourcesOnDeletion: true

  strategy:
     # The RollingSync update strategy allows you to group Applications by labels present on the generated Application resources
     # See documentation for "Progressive Syncs"
     type: RollingSync
     rollingSync:
      steps:
        # Application groups are selected using their labels and matchExpressions
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-dev
        # maxUpdate: 100%  # if undefined, all applications matched are updated together (default is 100%)
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-qa
          maxUpdate: 0      # if 0, no matched applications will be synced unless they're synced manually
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-prod
          maxUpdate: 10%    # maxUpdate supports both integer and percentage string values (rounds down, but floored at 1 Application for >0%)

  # Define annotations and labels of the Application that this ApplicationSet will ignore
  # ignoreApplicationDifferences is the preferred way to accomplish this now.
  preservedFields:
    annotations: [ some-annotation-key ]
    labels: [ some-label-key ]

  # Define fields of the that should be ignored when comparing Applications
  ignoreApplicationDifferences:
  - jsonPointers:
    - /spec/source/targetRevision
  - name: some-app
    jqPathExpressions:
    - .spec.source.helm.values

  