Repository: argoproj-labs/applicationset
Pull request #231 (2021-05-13 14:44:14)

Add duck type generator support to ApplicationSets (initial commit)
* Initial Commit
* Adds a Duck Type Generator to ApplicationSets that allows the controller to read an external Resource `Status.Decisions` (array) to determine the list of Argo CD clusters to deploy to.
* This approach uses the duck type Reference, that allows the user to define what resource will provide placement recommendations for target Argo CD clusters
* Duck Type Status definition:
```yaml
status:
  decisions:
  - clusterName: my-cluster01
  - clusterName: my-cluster02
```
* Duck Type Reference:
```yaml
spec:
  ducktType:
    apiVersion: my-group/v1beta1
    kind: MyKind
    name: my-resource-name
    requeueAfterSeconds: 60         # This is optional, default is 3 min
```
    

CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/argoproj-labs/applicationset?pullRequest=231) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/argoproj-labs/applicationset?pullRequest=231) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/argoproj-labs/applicationset?pullRequest=231) it.</sub>
jnpacker: * Rebased SCM changes.
* Issue Ref: https://github.com/argoproj-labs/applicationset/issues/158

OmerKahani: Thanks for this PR, is it a general purpose generator or a specific for Open Cluster Management? both are welcome, and will be very usfaul! but we might want to clarify it in the docs
jgwest: Thanks @jnpacker, I really like the idea of a generator based on using duck-types to provide values to ApplicationSet instances :tada:. 

One concern I have, which it sounds like is echoed by @OmerKahani  as well, is it may be too constrained to one specific 'shape' (eg that of OCM's placement rule).

If we wanted to implement a generator that was a fully generic duck-type based generator instance (that could be attached to ApplicationSets in order provide generic values) I would think we would want to change the expected shape...

For example, changing the expected `status` field from:
```yaml
status:
  decisions:                # Duck Type that is expected on the referenced resource
  - clusterName: cluster-01
```

to:
```yaml
status:
  parameters: 
    # parameters, rather than decisions, and untyped.
    # A generic []map[string]string, eg array of key-values 
    - name: cluster-01
      server: https://kubernetes.default.svc # note that requires the duck type's controller to read argo cd secrets to find the server url
```
and could also be:
```yaml
status:
  parameters:
    - someOtherKey: some other value
      anotherKey: another value
    - someOtherKey2: some other value
      anotherKey2: another value
```
(because `parameters` is just an array of generic key-value pairs, not typed to any particular schema)

In this model, a CR can contribute any set of key-value parameters that they want, which would be useful for replacing not only the built-in `cluster` generator, but also for replacing the other generators as well. (Granted, this is not EXACTLY the same as what you are proposing, because your PR does some additional work on the values eg checks that the clusters exist, and gets the URL for them from Argo CD, but I think these are not 100% essential functions)

So that would be how to generically use duck types to provide values to an ApplicationSet.

However, if the goal of the PR is primarily to connect to OCM PlacementRules, then it makes more sense to change the generator name to eg `ocmPlacementRule`, unless a case can be made that placement rules are themselves conceptual generic enough to fully represent other cluster management tools/user scenarios. For example, SkyScanner how has their own custom ApplicationSet-based controller which handles cluster selection:  https://github.com/Skyscanner/applicationset-progressive-sync

I'm :+1:  with adding explicit support for OCM-style PlacementRule, and it sounds like @OmerKahani is as well, but we would probably want to bring it up at the Argo CD community meeting to ensure there is agreement on enabling integration with a specific project (which would be a first for the ApplicationSet project: previously 'generators' have been tools that perform a specific function for a specific scenario).

What do you think, @jnpacker? :thinking: 

jnpacker: So being mindful of making the generator definition to complex, I might propose a default:

```yaml
status:
  generated:                # Pay homage to its roots
    - name: a value
      url: a value
    - name: some other value
      url: yet another value
```

Then allow an override using dynamic keys, in the generator DuckType spec:
```yaml
spec:
  ducktType:
    apiVersion: my-group/v1beta1
    kind: MyKind
    name: my-resource-name
    requeueAfterSeconds: 60         # This is optional, default is 3 min
    overrideParams:                 # OPTIONAL: 
      listKey: decisions             # OPTIONAL: Override for generated key
      nameKey: clusterName           # OPTIONAL: Override for name key
      urlKey: ""                     # OPTIONAL: Override for url key
```
Using something like this spec, you could define an ApplicationSet with generator DuckType and produce the target list of clusters in the `ProgressiveSync` Customer Resource status.

Its a little busy for the CLI, but should be fine for someone creating a UI that drives ApplicationSets.


jnpacker: Thinking about it a little more though, maybe to make it easier to consume:
```yaml
spec:
  ducktType:
    configMapRef: my-duck-type
    name: my-resource-name
---
kind: ConfigMap
metadata:
  name: my-duck-type
data:
  apiVersion: my-group/v1beta1
  kind: MyKind
  listKey: decisions
  nameKey: clusterName
  url: ""
  requeueAfterSeconds: 60
```

This way, you don't have to keep typing out the duckType parameters.  since everything lives in the argocd namespace, you could have a configMap for each duckType you wanted to leverage.

It also means creating application sets only requires two parameters to leverage the external resource.
jnpacker: So I wrote a new branch using a ConfigMap to identify the DuckType resource.  This actually works out to be very clean, as it now means you can dynamically choose a resource by specifying the resource `name` and the `configMapRef` (ConfigMap name) in the `ApplicationSet.Spec.Generators.DuckType`.  This is really nice, as it means you can have multiple resources, and you just have to change the name you use for configMapRef.
```yaml
spec:
  generators:
    - duckType:
        configMapRef: ocm-placement
        name: test-placement
        requeueAfterSeconds: 30
```
So with this in mind, I could have a `configMapRef: ocm-placement` and `configMapRef: skyscanner`, and create as many applicationSets as I want, re-using just those two configMaps.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ocm-placement
  namespace: argocd
data:
  apiVersion: apps.open-cluster-management.io/v1
  kind: placementrules
  statusListKey: parameters
  matchKey: name
```
The statusListKey and the matchKey allow support of more dynamic name choices, the statusListKey is `clusters` by default, but could be `parameters` or `decisions`
```yaml
...
status:
  parameters:
  - name: cluster1
  - name: cluster2
```
I did think for a while to allow skipping the validation code that compares the generated name to the ArgoCD clusters, but I noticed that if the Application created from the template is bad, the reconcile stops. So I opted to make sure the cluster coming from the duck resource always matches to an ArgoCD cluster by name.  This makes sure the reconcile always continues, since we never have an invalid cluster name in the Application template.

Last part, is I decided to include any Key/Values in the cluster list element from the resource to the template.  This allowed me to use `clusterName` from the OCM placement decision directly in the template, and will allow other resources to injected to the template.
https://github.com/argoproj-labs/applicationset/compare/master...jnpacker:duck-type-gen-cm?expand=1

Not sure if you'll have access to view the compare link above. Let me know what you think and I can replace this Pull with that one.

The other nice offshoot is someone tailoring a resource for use with this feature, just needs to include the ConfigMap with their resource bundle and make sure its created in the ArgoCD namespace.  At that point someone could start using it with ApplicationSets.
jnpacker: I'm also interested in your thoughts on using the ConfigMap vs included the 4x key / values in the duckType direcctly.

statusListKey and matchKey could be optional

statusListKey: `clusters`
matchKey: `name`

jgwest: Looking good, a couple questions:

**Q:** I am correct in that the principal difference between the configmap option, and the applicationset 'all fields in C'R option, is less reptition of fields (eg better DRY)? 

I presume both options have the same expressive 'power' (because the configmap just contains most of the same values that would otherwise be in the applicationset CR) but it's just less repitition. The ConfigMap approach feels more elegant to me, but I'd be curious if there was any other difference. 

**Q:** Even with the changes, I think we should still declare that this OCM is currently the only initial, existing consumer of this feature, but (paraphrasing) 'we hope it is flexible enough for other custom resources implementors that wish to define a set of clusters to target with their custom resource'. 

So that would be:
- Mention OCM as the current consumer in the docs
- Mention how we hope/it should be, suitable for others to use
- The generator will have a generic name that doesn't mention OCM (eg we don't need to call it ocmClusterPlacement or anything like that)
- 

If so, I will double check with Argo CD contributors that this integration is kosher, and we should be good. It's good that the type has been made more generic, and hopefully this will help other teams implementing custom cluster-targeting CRs :tada: .

And comments:

Since this generator is principally for targeting Applications to Clusters (vs some of the other generators that are not cluster focused), I think we should change the name to reflect that, keeping in mind that [naming things is hard](https://hilton.org.uk/blog/why-naming-things-is-hard). I'm thinking a `cluster` prefix, then something describing the fact that we are referencing a custom resource for the data:
	- clusterResourceRef
	- clusterCustomResource
	- clusterDuck :) :P
	- clusterDuckType
	- other ideas? 


> Last part, is I decided to include any Key/Values in the cluster list element from the resource to the template. This allowed me to use clusterName from the OCM placement decision directly in the template, and will allow other resources to injected to the template.
Sounds good.

> I did think for a while to allow skipping the validation code that compares the generated name to the ArgoCD clusters, but I noticed that if the Application created from the template is bad, the reconcile stops. 
Yah this is a bug that others have reported, which I've targeted for the current milestone: https://github.com/argoproj-labs/applicationset/issues/219
You can see the reasoning on that issue, but TLDR the controller should keep trying to reconcile on validation failure, and not give up.
(But, this is a moot point, as what you have in the PR is fine, keeping this check sounds good... I only brought this up in the context of exploring the idea of a more generic duck-type generator, which is a separate feature for another day)

Finally, I just want you to know that I LOL-ed at the `mallard.io` apiVersion  in the docs section of the PR :duck: :duck: :duck:  :smile: .
jgwest: ####  Looking good @jnpacker, a couple questions:

**Q:** I am correct that the principal difference between the ConfigMap option, and the ApplicationSet 'all fields in CR' option, is less reptition of fields (eg better DRY)? 

I presume both options have the same expressive 'power' (because the configmap just contains most of the same values that would otherwise be in the applicationset CR) but it's just less repitition. The ConfigMap approach feels more elegant to me, but I'm also curious if there was any other flexibility it grants. 

**Q:** Even with the changes, I think we should still declare that OCM is the only current existing consumer of this feature, but (paraphrasing) 'we hope it is flexible enough for other custom resources implementors that wish to define a set of clusters to target with their custom resource'. 

So that would be:
- Mention OCM as the current consumer in the docs
- Mention how we expect it should be suitable for others to use, and sufficiently document how they can use it
- I don't think we need to rename the generator to reference ocm...  I had previously mentioned renaming the generator to explicitly mention ocm (eg `ocmPlacementRule` or something like that), but the generator is now generic enough that is not necessary. But, see my name ideas below.

Sound good?

If so, I will double check with Argo CD contributors that this integration is kosher (I don't expect any issues), and we should be good. It's good that the type has been made more generic, and hopefully this will help other teams implementing custom cluster-targeting CRs :sunglasses: .

#### And comments:

Since this generator is principally for targeting Applications to Clusters (vs some of the other generators that are not cluster focused, like Git, and scm), I think we should change the name to reflect that, keeping in mind that [naming things is hard](https://hilton.org.uk/blog/why-naming-things-is-hard). I'm thinking a `cluster` prefix, then something describing the fact that we are referencing a custom resource for the data:
- clusterResourceRef
- clusterCustomResource
- clusterDuck :stuck_out_tongue: :smile: :thinking: 
- other ideas? 


> Last part, is I decided to include any Key/Values in the cluster list element from the resource to the template. This allowed me to use clusterName from the OCM placement decision directly in the template, and will allow other resources to injected to the template.

Sounds good.

> I did think for a while to allow skipping the validation code that compares the generated name to the ArgoCD clusters, but I noticed that if the Application created from the template is bad, the reconcile stops. 

Ah, this is a bug that others have reported, which I've targeted for the current milestone: https://github.com/argoproj-labs/applicationset/issues/219
You can see the reasoning on that issue, but TLDR the controller should keep trying to reconcile on validation failure, and not give up.
(But, this is a moot point, as what you have in the PR is fine, keeping this check as is sounds good... I only brought this up in the context of exploring the idea of a more generic duck-type generator, which is a separate feature for another day)

Finally, I just want you to know that I LOL-ed at the `mallard.io` apiVersion  in the docs section of the PR :duck: :duck: :duck:  :smile: .
jnpacker: A1. @jgwest, you are correct, it really just cuts down the repetition, and lowers the chance of a typo, as you only have to create one configMap for your target resource type per ArgoCD instance.

I thought it also made reading the ApplicationSet more elegant as you can leverage different resources with a simple descriptive name.

For the name.
```yaml
generators:
  - clusterResourceList:
       configMapRef:
       name: 
```
By calling the generator `Resource`, I think `name` works much better.  or clusterListResource or clusterCustomResource work. (If I though we could get away with ClusterDuck, I would use it 😜) 

A2. I'll add some OCM references to the generators.md

jgwest: @jnpacker Good suggestions, personally I like  `clusterListResource` generator, as it's a resource containing a cluster list (eg rather than a list of cluster resources, as in `clusterResourceList`).

Patch:
diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml
index d97db14..c95fba2 100644
--- a/.github/workflows/ci-build.yaml
+++ b/.github/workflows/ci-build.yaml
@@ -14,6 +14,10 @@ jobs:
     steps:
       - name: Checkout code
         uses: actions/checkout@v2
+      - name: Setup Golang
+        uses: actions/setup-go@v2
+        with:
+          go-version: '1.16.4'
       - name: Build Docker image
         run: |
           DOCKER_PUSH=false make image
@@ -25,9 +29,9 @@ jobs:
       - name: Checkout code
         uses: actions/checkout@v2
       - name: Setup Golang
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          go-version: '1.14.12'
+          go-version: '1.16.4'
       - name: Download all Go modules
         run: |
           go mod download
@@ -54,9 +58,9 @@ jobs:
       - name: Checkout code
         uses: actions/checkout@v2
       - name: Setup Golang
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          go-version: '1.14.12'
+          go-version: '1.16.4'
       - name: Restore go build cache
         uses: actions/cache@v1
         with:
@@ -78,7 +82,6 @@ jobs:
         uses: golangci/golangci-lint-action@v2
         with:
           version: v1.29
-          args: --timeout 5m --exclude SA5011,S1005
 
   test-go:
     name: Run unit tests for Go packages
@@ -93,9 +96,9 @@ jobs:
       - name: Create symlink in GOPATH
         run: ln -s $(pwd) ~/go/src/github.com/argoproj-labs
       - name: Setup Golang
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          go-version: '1.14.12'
+          go-version: '1.16.4'
       - name: Install required packages
         run: |
           sudo apt-get install git -y
@@ -160,15 +163,15 @@ jobs:
         with:
           repository: argoproj/argo-cd
           # Pin a specific commit to prevent Argo CD regressions from impacting us:
-          # This version is verified to match a version consistent with the kustomize install yaml, 
+          # This version is verified to match a version consistent with the kustomize install yaml,
           # by 'hack/verify-argo-cd-versions.sh'.
           # BEGIN-ARGO-CD-VERSION
           ref: v2.0.0
           # END-ARGO-CD-VERSION
       - name: Setup Golang
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          go-version: '1.14.12'
+          go-version: '1.16.4'
       # Add same workaround for port 8084 as argoproj/argo-cd #5658
       - name: GH actions workaround - Kill XSP4 process
         run: |
@@ -244,7 +247,7 @@ jobs:
           kubectl apply -f manifests/crds/argoproj.io_applicationsets.yaml
           make build
           make start-e2e 2>&1 | tee /tmp/appset-e2e-server.log &
-          # Uncomment this to see the Argo CD output alongside test output: 
+          # Uncomment this to see the Argo CD output alongside test output:
           # tail -f /tmp/e2e-server.log &
           make test-e2e
       - name: Upload e2e-server logs
@@ -259,5 +262,3 @@ jobs:
           name: argocd-e2e-server-k8s${{ matrix.k3s-version }}.log
           path: /tmp/e2e-server.log
         if: ${{ failure() }}
-
-        
\ No newline at end of file
diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml
new file mode 100644
index 0000000..e76e423
--- /dev/null
+++ b/.github/workflows/image.yaml
@@ -0,0 +1,33 @@
+name: Build image on commit to master
+
+on:
+  push:
+    branches:
+      - master
+
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+    env:
+      GOPATH: /home/runner/work/applicationset
+    steps:
+      - uses: actions/setup-go@v1
+        with:
+          go-version: '1.16.2'
+      - uses: actions/checkout@master
+        with:
+          path: src/applicationset
+
+      # Build the image
+      - run: |
+          docker images -a --format "{{.ID}}" | xargs -I {} docker rmi {}
+          CONTAINER_REGISTRY=quay.io IMAGE_NAMESPACE=argoproj IMAGE_TAG=latest make image
+        working-directory: ./src/applicationset
+
+      # Publish the image
+      - run: |
+          docker login quay.io --username $USERNAME --password $PASSWORD
+          docker push quay.io/argoproj/argocd-applicationset:latest
+        env:
+          USERNAME: ${{ secrets.USERNAME }}
+          PASSWORD: ${{ secrets.TOKEN }}
diff --git a/.golangci.yml b/.golangci.yml
index df6f3b9..98ee1dc 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,5 +1,5 @@
 run:
-  timeout: 2m
+  timeout: 5m
   skip-files:
   skip-dirs:
 linters:
@@ -12,3 +12,9 @@ linters:
     - ineffassign
     - unconvert
     - unparam
+output:
+  format: github-actions
+issues:
+  exclude:
+    - SA5011
+    - S1005
diff --git a/Makefile b/Makefile
index 34d6085..ed47356 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION?=$(shell cat VERSION)
-IMAGE_NAMESPACE?=argoprojlabs
+IMAGE_NAMESPACE?=argoproj
 IMAGE_NAME?=argocd-applicationset
 IMAGE_TAG?=latest
-CONTAINER_REGISTRY?=
+CONTAINER_REGISTRY?=quay.io
 
 MKDOCS_DOCKER_IMAGE?=squidfunk/mkdocs-material:4.1.1
 MKDOCS_RUN_ARGS?=
@@ -10,7 +10,7 @@ MKDOCS_RUN_ARGS?=
 CURRENT_DIR=$(shell pwd)
 
 KUSTOMIZE = $(shell pwd)/bin/kustomize
-
+CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
 
 ifdef IMAGE_NAMESPACE
 
@@ -57,7 +57,7 @@ deploy: kustomize manifests
 .PHONY: manifests
 manifests: kustomize generate
 	$(CONTROLLER_GEN) crd:crdVersions=v1 paths="./..." output:crd:artifacts:config=./manifests/crds/
-	KUSTOMIZE=${KUSTOMIZE} hack/generate-manifests.sh
+	KUSTOMIZE=${KUSTOMIZE} CONTAINER_REGISTRY=${CONTAINER_REGISTRY} hack/generate-manifests.sh
 
 .PHONY: lint
 lint:
@@ -76,7 +76,8 @@ vet:
 
 # Start the standalone controller for the purpose of running e2e tests
 .PHONY: start-e2e
-start-e2e:
+start-e2e: # Ensure the PlacementDecision CRD is present for the ClusterDecisionManagement tests
+	kubectl apply -f https://raw.githubusercontent.com/open-cluster-management/api/a6845f2ebcb186ec26b832f60c988537a58f3859/cluster/v1alpha1/0000_04_clusters.open-cluster-management.io_placementdecisions.crd.yaml
 	NAMESPACE=argocd-e2e "dist/argocd-applicationset" --metrics-addr=:12345 --probe-addr=:12346 --argocd-repo-server=localhost:8081 --namespace=argocd-e2e
 
 # Begin the tests, targetting the standalone controller (started by make start-e2e) and the e2e argo-cd (started by make start-e2e)
@@ -110,25 +111,11 @@ lint-docs:
 	find docs -name '*.md' -exec grep -l http {} + | xargs docker run --rm -v $(PWD):/mnt:ro dkhamsing/awesome_bot -t 3 --allow-dupe --allow-redirect --white-list `cat docs/assets/broken-link-ignore-list.txt | grep -v "#" | tr "\n" ','` --skip-save-results --
 
 
+controller-gen: ## Download controller-gen to '(project root)/bin', if not already present.
+	$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0)
 
-# find or download controller-gen
-# download controller-gen if necessary
-controller-gen:
-ifeq (, $(shell which controller-gen))
-	@{ \
-	set -e ;\
-	CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
-	cd $$CONTROLLER_GEN_TMP_DIR ;\
-	go mod init tmp ;\
-	go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0 ;\
-	rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
-	}
-CONTROLLER_GEN=$(GOBIN)/controller-gen
-else
-CONTROLLER_GEN=$(shell which controller-gen)
-endif
 
-kustomize: ## Download kustomize locally if necessary.
+kustomize: ## Download kustomize to '(project root)/bin', if not already present.
 	$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.9.4)
 
 # go-get-tool will 'go get' any package $2 and install it to $1.
diff --git a/api/v1alpha1/applicationset_types.go b/api/v1alpha1/applicationset_types.go
index c58b356..db52517 100644
--- a/api/v1alpha1/applicationset_types.go
+++ b/api/v1alpha1/applicationset_types.go
@@ -71,21 +71,23 @@ type ApplicationSetTemplateMeta struct {
 
 // ApplicationSetGenerator include list item info
 type ApplicationSetGenerator struct {
-	List        *ListGenerator        `json:"list,omitempty"`
-	Clusters    *ClusterGenerator     `json:"clusters,omitempty"`
-	Git         *GitGenerator         `json:"git,omitempty"`
-	Matrix      *MatrixGenerator      `json:"matrix,omitempty"`
-	SCMProvider *SCMProviderGenerator `json:"scmProvider,omitempty"`
+	List                    *ListGenerator        `json:"list,omitempty"`
+	Clusters                *ClusterGenerator     `json:"clusters,omitempty"`
+	Git                     *GitGenerator         `json:"git,omitempty"`
+	Matrix                  *MatrixGenerator      `json:"matrix,omitempty"`
+	SCMProvider             *SCMProviderGenerator `json:"scmProvider,omitempty"`
+	ClusterDecisionResource *DuckTypeGenerator    `json:"clusterDecisionResource,omitempty"`
 }
 
 // ApplicationSetBaseGenerator include list item info
 // CRD dosn't support recursive types so we need a different type for the matrix generator
 // https://github.com/kubernetes-sigs/controller-tools/issues/477
 type ApplicationSetBaseGenerator struct {
-	List        *ListGenerator        `json:"list,omitempty"`
-	Clusters    *ClusterGenerator     `json:"clusters,omitempty"`
-	Git         *GitGenerator         `json:"git,omitempty"`
-	SCMProvider *SCMProviderGenerator `json:"scmProvider,omitempty"`
+	List                    *ListGenerator        `json:"list,omitempty"`
+	Clusters                *ClusterGenerator     `json:"clusters,omitempty"`
+	Git                     *GitGenerator         `json:"git,omitempty"`
+	SCMProvider             *SCMProviderGenerator `json:"scmProvider,omitempty"`
+	ClusterDecisionResource *DuckTypeGenerator    `json:"clusterDecisionResource,omitempty"`
 }
 
 // ListGenerator include items info
@@ -120,6 +122,21 @@ type ClusterGenerator struct {
 	Values map[string]string `json:"values,omitempty"`
 }
 
+// DuckType defines a generator to match against clusters registered with ArgoCD.
+type DuckTypeGenerator struct {
+	// ConfigMapRef is a ConfigMap with the duck type definitions needed to retreive the data
+	//              this includes apiVersion(group/version), kind, matchKey and validation settings
+	// Name is the resource name of the kind, group and version, defined in the ConfigMapRef
+	// RequeueAfterSeconds is how long before the duckType will be rechecked for a change
+	ConfigMapRef        string `json:"configMapRef"`
+	Name                string `json:"name"`
+	RequeueAfterSeconds *int64 `json:"requeueAfterSeconds,omitempty"`
+
+	Template ApplicationSetTemplate `json:"template,omitempty"`
+	// Values contains key/value pairs which are passed directly as parameters to the template
+	Values map[string]string `json:"values,omitempty"`
+}
+
 type GitGenerator struct {
 	RepoURL             string                      `json:"repoURL"`
 	Directories         []GitDirectoryGeneratorItem `json:"directories,omitempty"`
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 44ecb99..a9b78eb 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -74,6 +74,11 @@ func (in *ApplicationSetBaseGenerator) DeepCopyInto(out *ApplicationSetBaseGener
 		*out = new(SCMProviderGenerator)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ClusterDecisionResource != nil {
+		in, out := &in.ClusterDecisionResource, &out.ClusterDecisionResource
+		*out = new(DuckTypeGenerator)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSetBaseGenerator.
@@ -114,6 +119,11 @@ func (in *ApplicationSetGenerator) DeepCopyInto(out *ApplicationSetGenerator) {
 		*out = new(SCMProviderGenerator)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ClusterDecisionResource != nil {
+		in, out := &in.ClusterDecisionResource, &out.ClusterDecisionResource
+		*out = new(DuckTypeGenerator)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSetGenerator.
@@ -286,6 +296,34 @@ func (in *ClusterGenerator) DeepCopy() *ClusterGenerator {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DuckTypeGenerator) DeepCopyInto(out *DuckTypeGenerator) {
+	*out = *in
+	if in.RequeueAfterSeconds != nil {
+		in, out := &in.RequeueAfterSeconds, &out.RequeueAfterSeconds
+		*out = new(int64)
+		**out = **in
+	}
+	in.Template.DeepCopyInto(&out.Template)
+	if in.Values != nil {
+		in, out := &in.Values, &out.Values
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DuckTypeGenerator.
+func (in *DuckTypeGenerator) DeepCopy() *DuckTypeGenerator {
+	if in == nil {
+		return nil
+	}
+	out := new(DuckTypeGenerator)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GitDirectoryGeneratorItem) DeepCopyInto(out *GitDirectoryGeneratorItem) {
 	*out = *in
diff --git a/docs/Generators.md b/docs/Generators.md
index e51c98d..987e21d 100644
--- a/docs/Generators.md
+++ b/docs/Generators.md
@@ -504,6 +504,7 @@ And our application yamls are defined in a git repository:
 
 Our goal is to deploy both application in both clusters. 
 For that we will use the matrix generator, with the git and the cluster as inner generators:
+
 ```yaml
 apiVersion: argoproj.io/v1alpha1
 kind: ApplicationSet
@@ -596,3 +597,69 @@ The matrix generators will combine both output and produce:
           template: # Ignored
        
 ```
+
+## Cluster List Resource Generator
+
+The cluster list resource generates a list of Argo CD clusters. This is done using [duck-typing](https://pkg.go.dev/knative.dev/pkg/apis/duck), which does not require knowledge of the full shape of the referenced kubernetes resource. The following is an example of the new ApplicationSet generator:
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: ApplicationSet
+metadata:
+ name: guestbook
+spec:
+ generators:
+ - clusterDecisionResource:
+    configMapRef: my-configmap  # ConfigMap with GVK information for the duck type resource
+    name: quak                  # The name of the resource
+    requeueAfterSeconds: 60     # OPTIONAL: Checks for changes every 60sec (default 3min)
+ template:
+   metadata:
+     name: '{{name}}-guestbook'
+   spec:
+      project: "default"
+      source:
+        repoURL: https://github.com/argoproj/argocd-example-apps/
+        targetRevision: HEAD
+        path: guestbook
+      destination:
+        server: '{{clusterName}}' # 'server' field of the secret
+        namespace: guestbook
+```
+The `quak` resource, referenced by the ApplicationSet `clusterDecisionResource` generator:
+```yaml
+apiVersion: mallard.io/v1beta1
+kind: Duck
+metadata:
+  name: quak
+spec: {}
+status:
+  decisions:     # Duck-typing ignores all other aspects of the resource except the "decisions" list
+  - clusterName: cluster-01
+  - clusterName: cluster-02
+```
+The ApplicationSet references a ConfigMap that defines the resource to be used in this duck-typing. Only one ConfigMap is required per ArgoCD instance, to identify a resource. You can support multiple resource types by creating a ConfigMap for each.
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: my-configmap
+data:
+  apiVersion: mallard.io/v1beta1  # apiVersion of the target resource
+  kind: ducks                     # kind of the target resource
+  statusListKey: decisions        # status key name that holds the list of ArgoCD clusters
+  matchKey: clusterName           # The key in the status list whose value is the cluster name found in ArgoCD
+```
+
+(*The full example can be found [here](https://github.com/argoproj-labs/applicationset/tree/master/examples/clusterDecisionResource).*)
+
+This example leverages the cluster management capabilities of the [open-cluster-management.io community](https://open-cluster-management.io/). By creating a ConfigMap with the GVK for the open-cluter-management.io Placement rule, your ApplicationSet can provision to different clusters in a number of novel ways. One example is to have the ApplicationSet maintain only two ArgoCD Applicaitons across 3 or more clusters. Then as maintenance or outages occur, the ApplicationSet will always maintain two Applications, moving the application to available clusters under the Placement rule's direction. 
+
+### How it works
+The ApplicationSet needs to be created in the ArgoCD namespace, placing the ConfigMap in the same namespace allows the ClusterDecisionResource generator to read it. The ConfigMap stores the GVK information as well as the status key definitions.  In the open-cluster-management example, the ApplicationSet generator will read the kind `placementrules` with an apiVersion of `apps.open-cluster-management.io/v1`. It will attempt to extract the **list** of clusters from the key `decisions`. It then validates the actual cluster name as defined in ArgoCD against the **value** from the key `clusterName` in each of the elements in the list.
+
+The ClusterDecisionResource generator passes the 'name', 'server' and any other key/value in the duck-type resource's status list as parameters into the ApplicationSet template. In this example, the decision array contained an additional key `clusterName`, which is now available to the ApplicationSet template.
+
+!!! note "Clusters listed as `Status.Decisions` must be predefined in Argo CD"
+    The cluster names listed in the `Status.Decisions` *must* be defined within Argo CD, in order to generate applications for these values. The ApplicationSet controller does not create clusters within Argo CD.
+
+    The Default Cluster list key is `clusters`.
\ No newline at end of file
diff --git a/examples/clusterDecisionResource/README.md b/examples/clusterDecisionResource/README.md
new file mode 100644
index 0000000..85ffe57
--- /dev/null
+++ b/examples/clusterDecisionResource/README.md
@@ -0,0 +1,57 @@
+# How the Cluster Decision Resource generator works for clusterDecisionResource
+1. The Cluster Decision Resource generator reads a configurable status format:
+```yaml
+status:
+  clusters:
+  - name: cluster-01
+  - name: cluster-02
+```
+This is a common status format.  Another format that could be read looks like this:
+```yaml
+status:
+  decisions:
+  - clusterName: cluster-01
+    namespace: cluster-01
+  - clusterName: cluster-02
+    namespace: cluster-02
+```
+2. Any resource that has a list of key / value pairs, where the value matches ArgoCD cluster names can be used.
+3. The key / value pairs found in each element of the list will be available to the template. As well, `name` and `server` will still be available to the template.
+4. The Service Account used by the ApplicationSet controller must have access to `Get` the resource you want to retrieve the duck type definition from
+5. A configMap is used to identify the resource to read status of generated ArgoCD clusters from. You can use multiple resources by creating a ConfigMap for each one in the ArgoCD namespace.
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: my-configmap
+data:
+  apiVersion: group.io/v1
+  kind: mykinds
+  statusListKey: clusters
+  matchKey: name
+```
+  * `apiVersion`    - This is the apiVersion of your resource
+  * `kind`          - This is the plural kind of your resource
+  * `statusListKey` - Default is 'clusters', this is the key found in your resource's status that is a list of ArgoCD clusters.
+  * `matchKey`      - Is the key name found in the cluster list, `name` and `clusterName` are the keys in the examples above.
+
+# Applying the example
+1. Connect to a cluster with the ApplicationSet controller running
+2. Edit the Role for the ApplicationSet service account, and grant it permission to `get` the `placementdecisions` resources, from apiGroups `cluster.open-cluster-management.io/v1alpha1`
+```yaml
+- apiGroups:
+  - "cluster.open-cluster-management.io/v1alpha1"
+  resources:
+  - placementdecisions
+  verbs:
+  - get
+```
+3. Apply the following controller and associated ManagedCluster CRD's:
+https://github.com/open-cluster-management/placement
+4. Now apply the PlacementDecision and an ApplicationSet:
+```bash
+kubectl apply -f ./placementdecision.yaml
+kubectl apply -f ./configMap.yaml
+kubectl apply -f ./ducktype-example.yaml
+```
+5. For now this won't do anything until you create a controller that populates the `Status.Decisions` array.
\ No newline at end of file
diff --git a/examples/clusterDecisionResource/configMap.yaml b/examples/clusterDecisionResource/configMap.yaml
new file mode 100644
index 0000000..69ddc81
--- /dev/null
+++ b/examples/clusterDecisionResource/configMap.yaml
@@ -0,0 +1,11 @@
+# To generate a Status.Decisions from this CRD, requires https://github.com/open-cluster-management/multicloud-operators-placementrule be deployed
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: ocm-placement
+data:
+  apiVersion: apps.open-cluster-management.io/v1
+  kind: placementrules
+  statusListKey: decisions
+  matchKey: clusterName
diff --git a/examples/clusterDecisionResource/ducktype-example.yaml b/examples/clusterDecisionResource/ducktype-example.yaml
new file mode 100644
index 0000000..1663bbb
--- /dev/null
+++ b/examples/clusterDecisionResource/ducktype-example.yaml
@@ -0,0 +1,27 @@
+apiVersion: argoproj.io/v1alpha1
+kind: ApplicationSet
+metadata:
+  name: book-import
+spec:
+  generators:
+    - clusterDecisionResource:
+        configMapRef: ocm-placement
+        name: test-placement
+        requeueAfterSeconds: 30
+  template:
+    metadata:
+      name: '{{clusterName}}-book-import'
+    spec:
+      project: "default"
+      source:
+        repoURL: https://github.com/open-cluster-management/application-samples.git
+        targetRevision: HEAD
+        path: book-import
+      destination:
+        name: '{{clusterName}}'
+        namespace: bookimport
+      syncPolicy:
+        automated:
+          prune: true
+        syncOptions:
+          - CreateNamespace=true
diff --git a/examples/clusterDecisionResource/placementdecision.yaml b/examples/clusterDecisionResource/placementdecision.yaml
new file mode 100644
index 0000000..666c2ac
--- /dev/null
+++ b/examples/clusterDecisionResource/placementdecision.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: apps.open-cluster-management.io/v1
+kind: PlacementRule
+metadata:
+  name: test-placement
+spec:
+  clusterReplicas: 1   # Availability choice, maximum number of clusters to provision at once
+  clusterSelector:
+    matchLabels:
+      'usage': 'development'
+  clusterConditions:
+    - type: ManagedClusterConditionAvailable
+      status: "True"
+# Below is sample output the generator can consume.
+status:
+  decisions:
+  - clusterName: cluster-01
+  - clusterName: cluster-02
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 0614b4f..1b5a2cb 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/argoproj-labs/applicationset
 
-go 1.14
+go 1.16
 
 require (
 	github.com/argoproj/argo-cd v1.8.1
diff --git a/go.sum b/go.sum
index 056d9a5..8694250 100644
--- a/go.sum
+++ b/go.sum
@@ -208,7 +208,6 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
diff --git a/hack/generate-manifests.sh b/hack/generate-manifests.sh
index e4bd516..15b7314 100755
--- a/hack/generate-manifests.sh
+++ b/hack/generate-manifests.sh
@@ -18,7 +18,7 @@ if [ "$CONTAINER_REGISTRY" != "" ]; then
 fi
 
 IMAGE_NAME="${IMAGE_NAME:-argocd-applicationset}"
-IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-argoprojlabs}"
+IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-argoproj}"
 IMAGE_TAG="${IMAGE_TAG:-}"
 
 # if the tag has not been declared, and we are on a release branch, use the VERSION file.
@@ -34,7 +34,7 @@ if [ "$IMAGE_TAG" = "" ]; then
   IMAGE_TAG=latest
 fi
 
-cd ${SRCROOT}/manifests/base && ${KUSTOMIZE} edit set image argoprojlabs/argocd-applicationset=${CONTAINER_REGISTRY}${IMAGE_NAMESPACE}/$IMAGE_NAME:${IMAGE_TAG}
+cd ${SRCROOT}/manifests/base && ${KUSTOMIZE} edit set image quay.io/argoproj/argocd-applicationset=${CONTAINER_REGISTRY}${IMAGE_NAMESPACE}/$IMAGE_NAME:${IMAGE_TAG}
 
 # Use kustomize to render 'manifests/install.yaml'
 echo "${AUTOGENMSG}" > ${TEMPFILE}
diff --git a/main.go b/main.go
index 5063c24..13d66db 100644
--- a/main.go
+++ b/main.go
@@ -35,6 +35,7 @@ import (
 	"github.com/argoproj/argo-cd/util/db"
 	argosettings "github.com/argoproj/argo-cd/util/settings"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/dynamic"
 	"k8s.io/client-go/kubernetes"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
@@ -70,6 +71,8 @@ func main() {
 	var policy string
 	var debugLog bool
 	var dryRun bool
+	var logLevel string
+
 	flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
 	flag.StringVar(&probeBindAddr, "probe-addr", ":8081", "The address the probe endpoint binds to.")
 	flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
@@ -78,7 +81,8 @@ func main() {
 	flag.StringVar(&namespace, "namespace", "", "Argo CD repo namespace (default: argocd)")
 	flag.StringVar(&argocdRepoServer, "argocd-repo-server", "argocd-repo-server:8081", "Argo CD repo server address")
 	flag.StringVar(&policy, "policy", "sync", "Modify how application is synced between the generator and the cluster. Default is 'sync' (create & update & delete), options: 'create-only', 'create-update' (no deletion)")
-	flag.BoolVar(&debugLog, "debug", false, "Print debug logs")
+	flag.BoolVar(&debugLog, "debug", false, "Print debug logs. Takes precedence over loglevel")
+	flag.StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
 	flag.BoolVar(&dryRun, "dry-run", false, "Enable dry run mode")
 	flag.Parse()
 
@@ -90,9 +94,7 @@ func main() {
 		os.Exit(1)
 	}
 
-	if debugLog {
-		log.SetLevel(log.DebugLevel)
-	}
+	setLoggingLevel(debugLog, logLevel)
 
 	// If user has not specified a namespace on the CLI, then use the value from NAMESPACE env var
 	if len(namespace) == 0 {
@@ -129,16 +131,18 @@ func main() {
 	}
 
 	k8s := kubernetes.NewForConfigOrDie(mgr.GetConfig())
+	dynClient := dynamic.NewForConfigOrDie(mgr.GetConfig())
 	argoSettingsMgr := argosettings.NewSettingsManager(context.Background(), k8s, namespace)
-	appclientset := appclientset.NewForConfigOrDie(mgr.GetConfig())
+	appSetConfig := appclientset.NewForConfigOrDie(mgr.GetConfig())
 
 	argoCDDB := db.NewDB(namespace, argoSettingsMgr, k8s)
 
 	baseGenerators := map[string]generators.Generator{
-		"List":        generators.NewListGenerator(),
-		"Clusters":    generators.NewClusterGenerator(mgr.GetClient(), context.Background(), k8s, namespace),
-		"Git":         generators.NewGitGenerator(services.NewArgoCDService(argoCDDB, argocdRepoServer)),
-		"SCMProvider": generators.NewSCMProviderGenerator(mgr.GetClient()),
+		"List":                    generators.NewListGenerator(),
+		"Clusters":                generators.NewClusterGenerator(mgr.GetClient(), context.Background(), k8s, namespace),
+		"Git":                     generators.NewGitGenerator(services.NewArgoCDService(argoCDDB, argocdRepoServer)),
+		"SCMProvider":             generators.NewSCMProviderGenerator(mgr.GetClient()),
+		"ClusterDecisionResource": generators.NewDuckTypeGenerator(context.Background(), dynClient, k8s, namespace),
 	}
 
 	combineGenerators := map[string]generators.Generator{
@@ -159,7 +163,7 @@ func main() {
 		Recorder:         mgr.GetEventRecorderFor("applicationset-controller"),
 		Renderer:         &utils.Render{},
 		Policy:           policyObj,
-		ArgoAppClientset: appclientset,
+		ArgoAppClientset: appSetConfig,
 		KubeClientset:    k8s,
 		ArgoDB:           argoCDDB,
 	}).SetupWithManager(mgr); err != nil {
@@ -177,3 +181,17 @@ func main() {
 		os.Exit(1)
 	}
 }
+
+func setLoggingLevel(debug bool, logLevel string) {
+	// the debug flag takes precedence over the loglevel flag
+	if debug {
+		log.SetLevel(log.DebugLevel)
+	} else {
+		level, err := log.ParseLevel(logLevel)
+		if err != nil {
+			setupLog.Error(err, "unable to parse loglevel", "loglevel", logLevel)
+			os.Exit(1)
+		}
+		log.SetLevel(level)
+	}
+}
diff --git a/manifests/base/deployment.yaml b/manifests/base/deployment.yaml
index a87a3c0..9bd7386 100644
--- a/manifests/base/deployment.yaml
+++ b/manifests/base/deployment.yaml
@@ -18,7 +18,7 @@ spec:
       containers:
         - command:
             - applicationset-controller
-          image: argoprojlabs/argocd-applicationset:latest
+          image: quay.io/argoproj/argocd-applicationset:latest
           imagePullPolicy: Always
           name: argocd-applicationset-controller
           env:
diff --git a/manifests/base/kustomization.yaml b/manifests/base/kustomization.yaml
index 17704ec..903b526 100644
--- a/manifests/base/kustomization.yaml
+++ b/manifests/base/kustomization.yaml
@@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
 kind: Kustomization
 
 images:
-- name: argoprojlabs/argocd-applicationset
-  newName: argoprojlabs/argocd-applicationset
+- name: quay.io/argoproj/argocd-applicationset
+  newName: quay.io/argoproj/argocd-applicationset
   newTag: latest
 
 namespace: argocd
diff --git a/manifests/crds/argoproj.io_applicationsets.yaml b/manifests/crds/argoproj.io_applicationsets.yaml
index bafcd4c..6870ece 100644
--- a/manifests/crds/argoproj.io_applicationsets.yaml
+++ b/manifests/crds/argoproj.io_applicationsets.yaml
@@ -44,58 +44,24 @@ spec:
                 items:
                   description: ApplicationSetGenerator include list item info
                   properties:
-                    clusters:
-                      description: ClusterGenerator defines a generator to match against
-                        clusters registered with ArgoCD.
+                    clusterDecisionResource:
+                      description: DuckType defines a generator to match against clusters
+                        registered with ArgoCD.
                       properties:
-                        selector:
-                          description: Selector defines a label selector to match
-                            against all clusters registered with ArgoCD. Clusters
-                            today are stored as Kubernetes Secrets, thus the Secret
-                            labels will be used for matching the selector.
-                          properties:
-                            matchExpressions:
-                              description: matchExpressions is a list of label selector
-                                requirements. The requirements are ANDed.
-                              items:
-                                description: A label selector requirement is a selector
-                                  that contains values, a key, and an operator that
-                                  relates the key and values.
-                                properties:
-                                  key:
-                                    description: key is the label key that the selector
-                                      applies to.
-                                    type: string
-                                  operator:
-                                    description: operator represents a key's relationship
-                                      to a set of values. Valid operators are In,
-                                      NotIn, Exists and DoesNotExist.
-                                    type: string
-                                  values:
-                                    description: values is an array of string values.
-                                      If the operator is In or NotIn, the values array
-                                      must be non-empty. If the operator is Exists
-                                      or DoesNotExist, the values array must be empty.
-                                      This array is replaced during a strategic merge
-                                      patch.
-                                    items:
-                                      type: string
-                                    type: array
-                                required:
-                                - key
-                                - operator
-                                type: object
-                              type: array
-                            matchLabels:
-                              additionalProperties:
-                                type: string
-                              description: matchLabels is a map of {key,value} pairs.
-                                A single {key,value} in the matchLabels map is equivalent
-                                to an element of matchExpressions, whose key field
-                                is "key", the operator is "In", and the values array
-                                contains only "value". The requirements are ANDed.
-                              type: object
-                          type: object
+                        configMapRef:
+                          description: ConfigMapRef is a ConfigMap with the duck type
+                            definitions needed to retreive the data              this
+                            includes apiVersion(group/version), kind, matchKey and
+                            validation settings Name is the resource name of the kind,
+                            group and version, defined in the ConfigMapRef RequeueAfterSeconds
+                            is how long before the duckType will be rechecked for
+                            a change
+                          type: string
+                        name:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -496,36 +462,62 @@ spec:
                           description: Values contains key/value pairs which are passed
                             directly as parameters to the template
                           type: object
+                      required:
+                      - configMapRef
+                      - name
                       type: object
-                    git:
+                    clusters:
+                      description: ClusterGenerator defines a generator to match against
+                        clusters registered with ArgoCD.
                       properties:
-                        directories:
-                          items:
-                            properties:
-                              exclude:
-                                type: boolean
-                              path:
-                                type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        files:
-                          items:
-                            properties:
-                              path:
+                        selector:
+                          description: Selector defines a label selector to match
+                            against all clusters registered with ArgoCD. Clusters
+                            today are stored as Kubernetes Secrets, thus the Secret
+                            labels will be used for matching the selector.
+                          properties:
+                            matchExpressions:
+                              description: matchExpressions is a list of label selector
+                                requirements. The requirements are ANDed.
+                              items:
+                                description: A label selector requirement is a selector
+                                  that contains values, a key, and an operator that
+                                  relates the key and values.
+                                properties:
+                                  key:
+                                    description: key is the label key that the selector
+                                      applies to.
+                                    type: string
+                                  operator:
+                                    description: operator represents a key's relationship
+                                      to a set of values. Valid operators are In,
+                                      NotIn, Exists and DoesNotExist.
+                                    type: string
+                                  values:
+                                    description: values is an array of string values.
+                                      If the operator is In or NotIn, the values array
+                                      must be non-empty. If the operator is Exists
+                                      or DoesNotExist, the values array must be empty.
+                                      This array is replaced during a strategic merge
+                                      patch.
+                                    items:
+                                      type: string
+                                    type: array
+                                required:
+                                - key
+                                - operator
+                                type: object
+                              type: array
+                            matchLabels:
+                              additionalProperties:
                                 type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        repoURL:
-                          type: string
-                        requeueAfterSeconds:
-                          format: int64
-                          type: integer
-                        revision:
-                          type: string
+                              description: matchLabels is a map of {key,value} pairs.
+                                A single {key,value} in the matchLabels map is equivalent
+                                to an element of matchExpressions, whose key field
+                                is "key", the operator is "In", and the values array
+                                contains only "value". The requirements are ANDed.
+                              type: object
+                          type: object
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -920,33 +912,42 @@ spec:
                           - metadata
                           - spec
                           type: object
-                      required:
-                      - repoURL
-                      - revision
+                        values:
+                          additionalProperties:
+                            type: string
+                          description: Values contains key/value pairs which are passed
+                            directly as parameters to the template
+                          type: object
                       type: object
-                    list:
-                      description: ListGenerator include items info
+                    git:
                       properties:
-                        elements:
+                        directories:
                           items:
-                            description: ListGeneratorElement include cluster and
-                              url info
                             properties:
-                              cluster:
+                              exclude:
+                                type: boolean
+                              path:
                                 type: string
-                              url:
+                            required:
+                            - path
+                            type: object
+                          type: array
+                        files:
+                          items:
+                            properties:
+                              path:
                                 type: string
-                              values:
-                                additionalProperties:
-                                  type: string
-                                description: Values contains key/value pairs which
-                                  are passed directly as parameters to the template
-                                type: object
                             required:
-                            - cluster
-                            - url
+                            - path
                             type: object
                           type: array
+                        repoURL:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
+                        revision:
+                          type: string
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -1342,17 +1343,894 @@ spec:
                           - spec
                           type: object
                       required:
-                      - elements
+                      - repoURL
+                      - revision
                       type: object
-                    matrix:
-                      description: MatrixGenerator include Other generators
+                    list:
+                      description: ListGenerator include items info
                       properties:
-                        generators:
+                        elements:
                           items:
-                            description: ApplicationSetBaseGenerator include list
-                              item info CRD dosn't support recursive types so we need
-                              a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            description: ListGeneratorElement include cluster and
+                              url info
                             properties:
+                              cluster:
+                                type: string
+                              url:
+                                type: string
+                              values:
+                                additionalProperties:
+                                  type: string
+                                description: Values contains key/value pairs which
+                                  are passed directly as parameters to the template
+                                type: object
+                            required:
+                            - cluster
+                            - url
+                            type: object
+                          type: array
+                        template:
+                          description: ApplicationSetTemplate represents argocd ApplicationSpec
+                          properties:
+                            metadata:
+                              description: ApplicationSetTemplateMeta represents the
+                                Argo CD application fields that may be used for Applications
+                                generated from the ApplicationSet (based on metav1.ObjectMeta)
+                              properties:
+                                annotations:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                labels:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                name:
+                                  type: string
+                                namespace:
+                                  type: string
+                              type: object
+                            spec:
+                              description: ApplicationSpec represents desired application
+                                state. Contains link to repository with application
+                                definition and additional parameters link definition
+                                revision.
+                              properties:
+                                destination:
+                                  description: Destination overrides the kubernetes
+                                    server and namespace defined in the environment
+                                    ksonnet app.yaml
+                                  properties:
+                                    name:
+                                      description: Name of the destination cluster
+                                        which can be used instead of server (url)
+                                        field
+                                      type: string
+                                    namespace:
+                                      description: Namespace overrides the environment
+                                        namespace value in the ksonnet app.yaml
+                                      type: string
+                                    server:
+                                      description: Server overrides the environment
+                                        server value in the ksonnet app.yaml
+                                      type: string
+                                  type: object
+                                ignoreDifferences:
+                                  description: IgnoreDifferences controls resources
+                                    fields which should be ignored during comparison
+                                  items:
+                                    description: ResourceIgnoreDifferences contains
+                                      resource filter and list of json paths which
+                                      should be ignored during comparison with live
+                                      state.
+                                    properties:
+                                      group:
+                                        type: string
+                                      jsonPointers:
+                                        items:
+                                          type: string
+                                        type: array
+                                      kind:
+                                        type: string
+                                      name:
+                                        type: string
+                                      namespace:
+                                        type: string
+                                    required:
+                                    - jsonPointers
+                                    - kind
+                                    type: object
+                                  type: array
+                                info:
+                                  description: Infos contains a list of useful information
+                                    (URLs, email addresses, and plain text) that relates
+                                    to the application
+                                  items:
+                                    properties:
+                                      name:
+                                        type: string
+                                      value:
+                                        type: string
+                                    required:
+                                    - name
+                                    - value
+                                    type: object
+                                  type: array
+                                project:
+                                  description: Project is a application project name.
+                                    Empty name means that application belongs to 'default'
+                                    project.
+                                  type: string
+                                revisionHistoryLimit:
+                                  description: This limits this number of items kept
+                                    in the apps revision history. This should only
+                                    be changed in exceptional circumstances. Setting
+                                    to zero will store no history. This will reduce
+                                    storage used. Increasing will increase the space
+                                    used to store the history, so we do not recommend
+                                    increasing it. Default is 10.
+                                  format: int64
+                                  type: integer
+                                source:
+                                  description: Source is a reference to the location
+                                    ksonnet application definition
+                                  properties:
+                                    chart:
+                                      description: Chart is a Helm chart name
+                                      type: string
+                                    directory:
+                                      description: Directory holds path/directory
+                                        specific options
+                                      properties:
+                                        exclude:
+                                          type: string
+                                        jsonnet:
+                                          description: ApplicationSourceJsonnet holds
+                                            jsonnet specific options
+                                          properties:
+                                            extVars:
+                                              description: ExtVars is a list of Jsonnet
+                                                External Variables
+                                              items:
+                                                description: JsonnetVar is a jsonnet
+                                                  variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                            libs:
+                                              description: Additional library search
+                                                dirs
+                                              items:
+                                                type: string
+                                              type: array
+                                            tlas:
+                                              description: TLAS is a list of Jsonnet
+                                                Top-level Arguments
+                                              items:
+                                                description: JsonnetVar is a jsonnet
+                                                  variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                          type: object
+                                        recurse:
+                                          type: boolean
+                                      type: object
+                                    helm:
+                                      description: Helm holds helm specific options
+                                      properties:
+                                        fileParameters:
+                                          description: FileParameters are file parameters
+                                            to the helm template
+                                          items:
+                                            description: HelmFileParameter is a file
+                                              parameter to a helm template
+                                            properties:
+                                              name:
+                                                description: Name is the name of the
+                                                  helm parameter
+                                                type: string
+                                              path:
+                                                description: Path is the path value
+                                                  for the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        parameters:
+                                          description: Parameters are parameters to
+                                            the helm template
+                                          items:
+                                            description: HelmParameter is a parameter
+                                              to a helm template
+                                            properties:
+                                              forceString:
+                                                description: ForceString determines
+                                                  whether to tell Helm to interpret
+                                                  booleans and numbers as strings
+                                                type: boolean
+                                              name:
+                                                description: Name is the name of the
+                                                  helm parameter
+                                                type: string
+                                              value:
+                                                description: Value is the value for
+                                                  the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        releaseName:
+                                          description: The Helm release name. If omitted
+                                            it will use the application name
+                                          type: string
+                                        valueFiles:
+                                          description: ValuesFiles is a list of Helm
+                                            value files to use when generating a template
+                                          items:
+                                            type: string
+                                          type: array
+                                        values:
+                                          description: Values is Helm values, typically
+                                            defined as a block
+                                          type: string
+                                        version:
+                                          description: Version is the Helm version
+                                            to use for templating with
+                                          type: string
+                                      type: object
+                                    ksonnet:
+                                      description: Ksonnet holds ksonnet specific
+                                        options
+                                      properties:
+                                        environment:
+                                          description: Environment is a ksonnet application
+                                            environment name
+                                          type: string
+                                        parameters:
+                                          description: Parameters are a list of ksonnet
+                                            component parameter override values
+                                          items:
+                                            description: KsonnetParameter is a ksonnet
+                                              component parameter
+                                            properties:
+                                              component:
+                                                type: string
+                                              name:
+                                                type: string
+                                              value:
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                      type: object
+                                    kustomize:
+                                      description: Kustomize holds kustomize specific
+                                        options
+                                      properties:
+                                        commonAnnotations:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonAnnotations adds additional
+                                            kustomize commonAnnotations
+                                          type: object
+                                        commonLabels:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonLabels adds additional
+                                            kustomize commonLabels
+                                          type: object
+                                        images:
+                                          description: Images are kustomize image
+                                            overrides
+                                          items:
+                                            type: string
+                                          type: array
+                                        namePrefix:
+                                          description: NamePrefix is a prefix appended
+                                            to resources for kustomize apps
+                                          type: string
+                                        nameSuffix:
+                                          description: NameSuffix is a suffix appended
+                                            to resources for kustomize apps
+                                          type: string
+                                        version:
+                                          description: Version contains optional Kustomize
+                                            version
+                                          type: string
+                                      type: object
+                                    path:
+                                      description: Path is a directory path within
+                                        the Git repository
+                                      type: string
+                                    plugin:
+                                      description: ConfigManagementPlugin holds config
+                                        management plugin specific options
+                                      properties:
+                                        env:
+                                          items:
+                                            properties:
+                                              name:
+                                                description: the name, usually uppercase
+                                                type: string
+                                              value:
+                                                description: the value
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                        name:
+                                          type: string
+                                      type: object
+                                    repoURL:
+                                      description: RepoURL is the repository URL of
+                                        the application manifests
+                                      type: string
+                                    targetRevision:
+                                      description: TargetRevision defines the commit,
+                                        tag, or branch in which to sync the application
+                                        to. If omitted, will sync to HEAD
+                                      type: string
+                                  required:
+                                  - repoURL
+                                  type: object
+                                syncPolicy:
+                                  description: SyncPolicy controls when a sync will
+                                    be performed
+                                  properties:
+                                    automated:
+                                      description: Automated will keep an application
+                                        synced to the target revision
+                                      properties:
+                                        allowEmpty:
+                                          description: 'AllowEmpty allows apps have
+                                            zero live resources (default: false)'
+                                          type: boolean
+                                        prune:
+                                          description: 'Prune will prune resources
+                                            automatically as part of automated sync
+                                            (default: false)'
+                                          type: boolean
+                                        selfHeal:
+                                          description: 'SelfHeal enables auto-syncing
+                                            if  (default: false)'
+                                          type: boolean
+                                      type: object
+                                    retry:
+                                      description: Retry controls failed sync retry
+                                        behavior
+                                      properties:
+                                        backoff:
+                                          description: Backoff is a backoff strategy
+                                          properties:
+                                            duration:
+                                              description: Duration is the amount
+                                                to back off. Default unit is seconds,
+                                                but could also be a duration (e.g.
+                                                "2m", "1h")
+                                              type: string
+                                            factor:
+                                              description: Factor is a factor to multiply
+                                                the base duration after each failed
+                                                retry
+                                              format: int64
+                                              type: integer
+                                            maxDuration:
+                                              description: MaxDuration is the maximum
+                                                amount of time allowed for the backoff
+                                                strategy
+                                              type: string
+                                          type: object
+                                        limit:
+                                          description: Limit is the maximum number
+                                            of attempts when retrying a container
+                                          format: int64
+                                          type: integer
+                                      type: object
+                                    syncOptions:
+                                      description: Options allow you to specify whole
+                                        app sync-options
+                                      items:
+                                        type: string
+                                      type: array
+                                  type: object
+                              required:
+                              - destination
+                              - project
+                              - source
+                              type: object
+                          required:
+                          - metadata
+                          - spec
+                          type: object
+                      required:
+                      - elements
+                      type: object
+                    matrix:
+                      description: MatrixGenerator include Other generators
+                      properties:
+                        generators:
+                          items:
+                            description: ApplicationSetBaseGenerator include list
+                              item info CRD dosn't support recursive types so we need
+                              a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            properties:
+                              clusterDecisionResource:
+                                description: DuckType defines a generator to match
+                                  against clusters registered with ArgoCD.
+                                properties:
+                                  configMapRef:
+                                    description: ConfigMapRef is a ConfigMap with
+                                      the duck type definitions needed to retreive
+                                      the data              this includes apiVersion(group/version),
+                                      kind, matchKey and validation settings Name
+                                      is the resource name of the kind, group and
+                                      version, defined in the ConfigMapRef RequeueAfterSeconds
+                                      is how long before the duckType will be rechecked
+                                      for a change
+                                    type: string
+                                  name:
+                                    type: string
+                                  requeueAfterSeconds:
+                                    format: int64
+                                    type: integer
+                                  template:
+                                    description: ApplicationSetTemplate represents
+                                      argocd ApplicationSpec
+                                    properties:
+                                      metadata:
+                                        description: ApplicationSetTemplateMeta represents
+                                          the Argo CD application fields that may
+                                          be used for Applications generated from
+                                          the ApplicationSet (based on metav1.ObjectMeta)
+                                        properties:
+                                          annotations:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          labels:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          name:
+                                            type: string
+                                          namespace:
+                                            type: string
+                                        type: object
+                                      spec:
+                                        description: ApplicationSpec represents desired
+                                          application state. Contains link to repository
+                                          with application definition and additional
+                                          parameters link definition revision.
+                                        properties:
+                                          destination:
+                                            description: Destination overrides the
+                                              kubernetes server and namespace defined
+                                              in the environment ksonnet app.yaml
+                                            properties:
+                                              name:
+                                                description: Name of the destination
+                                                  cluster which can be used instead
+                                                  of server (url) field
+                                                type: string
+                                              namespace:
+                                                description: Namespace overrides the
+                                                  environment namespace value in the
+                                                  ksonnet app.yaml
+                                                type: string
+                                              server:
+                                                description: Server overrides the
+                                                  environment server value in the
+                                                  ksonnet app.yaml
+                                                type: string
+                                            type: object
+                                          ignoreDifferences:
+                                            description: IgnoreDifferences controls
+                                              resources fields which should be ignored
+                                              during comparison
+                                            items:
+                                              description: ResourceIgnoreDifferences
+                                                contains resource filter and list
+                                                of json paths which should be ignored
+                                                during comparison with live state.
+                                              properties:
+                                                group:
+                                                  type: string
+                                                jsonPointers:
+                                                  items:
+                                                    type: string
+                                                  type: array
+                                                kind:
+                                                  type: string
+                                                name:
+                                                  type: string
+                                                namespace:
+                                                  type: string
+                                              required:
+                                              - jsonPointers
+                                              - kind
+                                              type: object
+                                            type: array
+                                          info:
+                                            description: Infos contains a list of
+                                              useful information (URLs, email addresses,
+                                              and plain text) that relates to the
+                                              application
+                                            items:
+                                              properties:
+                                                name:
+                                                  type: string
+                                                value:
+                                                  type: string
+                                              required:
+                                              - name
+                                              - value
+                                              type: object
+                                            type: array
+                                          project:
+                                            description: Project is a application
+                                              project name. Empty name means that
+                                              application belongs to 'default' project.
+                                            type: string
+                                          revisionHistoryLimit:
+                                            description: This limits this number of
+                                              items kept in the apps revision history.
+                                              This should only be changed in exceptional
+                                              circumstances. Setting to zero will
+                                              store no history. This will reduce storage
+                                              used. Increasing will increase the space
+                                              used to store the history, so we do
+                                              not recommend increasing it. Default
+                                              is 10.
+                                            format: int64
+                                            type: integer
+                                          source:
+                                            description: Source is a reference to
+                                              the location ksonnet application definition
+                                            properties:
+                                              chart:
+                                                description: Chart is a Helm chart
+                                                  name
+                                                type: string
+                                              directory:
+                                                description: Directory holds path/directory
+                                                  specific options
+                                                properties:
+                                                  exclude:
+                                                    type: string
+                                                  jsonnet:
+                                                    description: ApplicationSourceJsonnet
+                                                      holds jsonnet specific options
+                                                    properties:
+                                                      extVars:
+                                                        description: ExtVars is a
+                                                          list of Jsonnet External
+                                                          Variables
+                                                        items:
+                                                          description: JsonnetVar
+                                                            is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                      libs:
+                                                        description: Additional library
+                                                          search dirs
+                                                        items:
+                                                          type: string
+                                                        type: array
+                                                      tlas:
+                                                        description: TLAS is a list
+                                                          of Jsonnet Top-level Arguments
+                                                        items:
+                                                          description: JsonnetVar
+                                                            is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                    type: object
+                                                  recurse:
+                                                    type: boolean
+                                                type: object
+                                              helm:
+                                                description: Helm holds helm specific
+                                                  options
+                                                properties:
+                                                  fileParameters:
+                                                    description: FileParameters are
+                                                      file parameters to the helm
+                                                      template
+                                                    items:
+                                                      description: HelmFileParameter
+                                                        is a file parameter to a helm
+                                                        template
+                                                      properties:
+                                                        name:
+                                                          description: Name is the
+                                                            name of the helm parameter
+                                                          type: string
+                                                        path:
+                                                          description: Path is the
+                                                            path value for the helm
+                                                            parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  parameters:
+                                                    description: Parameters are parameters
+                                                      to the helm template
+                                                    items:
+                                                      description: HelmParameter is
+                                                        a parameter to a helm template
+                                                      properties:
+                                                        forceString:
+                                                          description: ForceString
+                                                            determines whether to
+                                                            tell Helm to interpret
+                                                            booleans and numbers as
+                                                            strings
+                                                          type: boolean
+                                                        name:
+                                                          description: Name is the
+                                                            name of the helm parameter
+                                                          type: string
+                                                        value:
+                                                          description: Value is the
+                                                            value for the helm parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  releaseName:
+                                                    description: The Helm release
+                                                      name. If omitted it will use
+                                                      the application name
+                                                    type: string
+                                                  valueFiles:
+                                                    description: ValuesFiles is a
+                                                      list of Helm value files to
+                                                      use when generating a template
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  values:
+                                                    description: Values is Helm values,
+                                                      typically defined as a block
+                                                    type: string
+                                                  version:
+                                                    description: Version is the Helm
+                                                      version to use for templating
+                                                      with
+                                                    type: string
+                                                type: object
+                                              ksonnet:
+                                                description: Ksonnet holds ksonnet
+                                                  specific options
+                                                properties:
+                                                  environment:
+                                                    description: Environment is a
+                                                      ksonnet application environment
+                                                      name
+                                                    type: string
+                                                  parameters:
+                                                    description: Parameters are a
+                                                      list of ksonnet component parameter
+                                                      override values
+                                                    items:
+                                                      description: KsonnetParameter
+                                                        is a ksonnet component parameter
+                                                      properties:
+                                                        component:
+                                                          type: string
+                                                        name:
+                                                          type: string
+                                                        value:
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                type: object
+                                              kustomize:
+                                                description: Kustomize holds kustomize
+                                                  specific options
+                                                properties:
+                                                  commonAnnotations:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonAnnotations
+                                                      adds additional kustomize commonAnnotations
+                                                    type: object
+                                                  commonLabels:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonLabels adds
+                                                      additional kustomize commonLabels
+                                                    type: object
+                                                  images:
+                                                    description: Images are kustomize
+                                                      image overrides
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  namePrefix:
+                                                    description: NamePrefix is a prefix
+                                                      appended to resources for kustomize
+                                                      apps
+                                                    type: string
+                                                  nameSuffix:
+                                                    description: NameSuffix is a suffix
+                                                      appended to resources for kustomize
+                                                      apps
+                                                    type: string
+                                                  version:
+                                                    description: Version contains
+                                                      optional Kustomize version
+                                                    type: string
+                                                type: object
+                                              path:
+                                                description: Path is a directory path
+                                                  within the Git repository
+                                                type: string
+                                              plugin:
+                                                description: ConfigManagementPlugin
+                                                  holds config management plugin specific
+                                                  options
+                                                properties:
+                                                  env:
+                                                    items:
+                                                      properties:
+                                                        name:
+                                                          description: the name, usually
+                                                            uppercase
+                                                          type: string
+                                                        value:
+                                                          description: the value
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                  name:
+                                                    type: string
+                                                type: object
+                                              repoURL:
+                                                description: RepoURL is the repository
+                                                  URL of the application manifests
+                                                type: string
+                                              targetRevision:
+                                                description: TargetRevision defines
+                                                  the commit, tag, or branch in which
+                                                  to sync the application to. If omitted,
+                                                  will sync to HEAD
+                                                type: string
+                                            required:
+                                            - repoURL
+                                            type: object
+                                          syncPolicy:
+                                            description: SyncPolicy controls when
+                                              a sync will be performed
+                                            properties:
+                                              automated:
+                                                description: Automated will keep an
+                                                  application synced to the target
+                                                  revision
+                                                properties:
+                                                  allowEmpty:
+                                                    description: 'AllowEmpty allows
+                                                      apps have zero live resources
+                                                      (default: false)'
+                                                    type: boolean
+                                                  prune:
+                                                    description: 'Prune will prune
+                                                      resources automatically as part
+                                                      of automated sync (default:
+                                                      false)'
+                                                    type: boolean
+                                                  selfHeal:
+                                                    description: 'SelfHeal enables
+                                                      auto-syncing if  (default: false)'
+                                                    type: boolean
+                                                type: object
+                                              retry:
+                                                description: Retry controls failed
+                                                  sync retry behavior
+                                                properties:
+                                                  backoff:
+                                                    description: Backoff is a backoff
+                                                      strategy
+                                                    properties:
+                                                      duration:
+                                                        description: Duration is the
+                                                          amount to back off. Default
+                                                          unit is seconds, but could
+                                                          also be a duration (e.g.
+                                                          "2m", "1h")
+                                                        type: string
+                                                      factor:
+                                                        description: Factor is a factor
+                                                          to multiply the base duration
+                                                          after each failed retry
+                                                        format: int64
+                                                        type: integer
+                                                      maxDuration:
+                                                        description: MaxDuration is
+                                                          the maximum amount of time
+                                                          allowed for the backoff
+                                                          strategy
+                                                        type: string
+                                                    type: object
+                                                  limit:
+                                                    description: Limit is the maximum
+                                                      number of attempts when retrying
+                                                      a container
+                                                    format: int64
+                                                    type: integer
+                                                type: object
+                                              syncOptions:
+                                                description: Options allow you to
+                                                  specify whole app sync-options
+                                                items:
+                                                  type: string
+                                                type: array
+                                            type: object
+                                        required:
+                                        - destination
+                                        - project
+                                        - source
+                                        type: object
+                                    required:
+                                    - metadata
+                                    - spec
+                                    type: object
+                                  values:
+                                    additionalProperties:
+                                      type: string
+                                    description: Values contains key/value pairs which
+                                      are passed directly as parameters to the template
+                                    type: object
+                                required:
+                                - configMapRef
+                                - name
+                                type: object
                               clusters:
                                 description: ClusterGenerator defines a generator
                                   to match against clusters registered with ArgoCD.
diff --git a/manifests/install-with-argo-cd.yaml b/manifests/install-with-argo-cd.yaml
index 5e0e944..0cbdb45 100644
--- a/manifests/install-with-argo-cd.yaml
+++ b/manifests/install-with-argo-cd.yaml
@@ -1799,39 +1799,17 @@ spec:
                 items:
                   description: ApplicationSetGenerator include list item info
                   properties:
-                    clusters:
-                      description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
+                    clusterDecisionResource:
+                      description: DuckType defines a generator to match against clusters registered with ArgoCD.
                       properties:
-                        selector:
-                          description: Selector defines a label selector to match against all clusters registered with ArgoCD. Clusters today are stored as Kubernetes Secrets, thus the Secret labels will be used for matching the selector.
-                          properties:
-                            matchExpressions:
-                              description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
-                              items:
-                                description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
-                                properties:
-                                  key:
-                                    description: key is the label key that the selector applies to.
-                                    type: string
-                                  operator:
-                                    description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
-                                    type: string
-                                  values:
-                                    description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
-                                    items:
-                                      type: string
-                                    type: array
-                                required:
-                                - key
-                                - operator
-                                type: object
-                              type: array
-                            matchLabels:
-                              additionalProperties:
-                                type: string
-                              description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
-                              type: object
-                          type: object
+                        configMapRef:
+                          description: ConfigMapRef is a ConfigMap with the duck type definitions needed to retreive the data              this includes apiVersion(group/version), kind, matchKey and validation settings Name is the resource name of the kind, group and version, defined in the ConfigMapRef RequeueAfterSeconds is how long before the duckType will be rechecked for a change
+                          type: string
+                        name:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -2152,36 +2130,43 @@ spec:
                             type: string
                           description: Values contains key/value pairs which are passed directly as parameters to the template
                           type: object
+                      required:
+                      - configMapRef
+                      - name
                       type: object
-                    git:
+                    clusters:
+                      description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
                       properties:
-                        directories:
-                          items:
-                            properties:
-                              exclude:
-                                type: boolean
-                              path:
-                                type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        files:
-                          items:
-                            properties:
-                              path:
+                        selector:
+                          description: Selector defines a label selector to match against all clusters registered with ArgoCD. Clusters today are stored as Kubernetes Secrets, thus the Secret labels will be used for matching the selector.
+                          properties:
+                            matchExpressions:
+                              description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
+                              items:
+                                description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
+                                properties:
+                                  key:
+                                    description: key is the label key that the selector applies to.
+                                    type: string
+                                  operator:
+                                    description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
+                                    type: string
+                                  values:
+                                    description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
+                                    items:
+                                      type: string
+                                    type: array
+                                required:
+                                - key
+                                - operator
+                                type: object
+                              type: array
+                            matchLabels:
+                              additionalProperties:
                                 type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        repoURL:
-                          type: string
-                        requeueAfterSeconds:
-                          format: int64
-                          type: integer
-                        revision:
-                          type: string
+                              description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
+                              type: object
+                          type: object
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -2497,31 +2482,41 @@ spec:
                           - metadata
                           - spec
                           type: object
-                      required:
-                      - repoURL
-                      - revision
+                        values:
+                          additionalProperties:
+                            type: string
+                          description: Values contains key/value pairs which are passed directly as parameters to the template
+                          type: object
                       type: object
-                    list:
-                      description: ListGenerator include items info
+                    git:
                       properties:
-                        elements:
+                        directories:
                           items:
-                            description: ListGeneratorElement include cluster and url info
                             properties:
-                              cluster:
+                              exclude:
+                                type: boolean
+                              path:
                                 type: string
-                              url:
+                            required:
+                            - path
+                            type: object
+                          type: array
+                        files:
+                          items:
+                            properties:
+                              path:
                                 type: string
-                              values:
-                                additionalProperties:
-                                  type: string
-                                description: Values contains key/value pairs which are passed directly as parameters to the template
-                                type: object
                             required:
-                            - cluster
-                            - url
+                            - path
                             type: object
                           type: array
+                        repoURL:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
+                        revision:
+                          type: string
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -2838,15 +2833,690 @@ spec:
                           - spec
                           type: object
                       required:
-                      - elements
+                      - repoURL
+                      - revision
                       type: object
-                    matrix:
-                      description: MatrixGenerator include Other generators
+                    list:
+                      description: ListGenerator include items info
                       properties:
-                        generators:
+                        elements:
                           items:
-                            description: ApplicationSetBaseGenerator include list item info CRD dosn't support recursive types so we need a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            description: ListGeneratorElement include cluster and url info
                             properties:
+                              cluster:
+                                type: string
+                              url:
+                                type: string
+                              values:
+                                additionalProperties:
+                                  type: string
+                                description: Values contains key/value pairs which are passed directly as parameters to the template
+                                type: object
+                            required:
+                            - cluster
+                            - url
+                            type: object
+                          type: array
+                        template:
+                          description: ApplicationSetTemplate represents argocd ApplicationSpec
+                          properties:
+                            metadata:
+                              description: ApplicationSetTemplateMeta represents the Argo CD application fields that may be used for Applications generated from the ApplicationSet (based on metav1.ObjectMeta)
+                              properties:
+                                annotations:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                labels:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                name:
+                                  type: string
+                                namespace:
+                                  type: string
+                              type: object
+                            spec:
+                              description: ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.
+                              properties:
+                                destination:
+                                  description: Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml
+                                  properties:
+                                    name:
+                                      description: Name of the destination cluster which can be used instead of server (url) field
+                                      type: string
+                                    namespace:
+                                      description: Namespace overrides the environment namespace value in the ksonnet app.yaml
+                                      type: string
+                                    server:
+                                      description: Server overrides the environment server value in the ksonnet app.yaml
+                                      type: string
+                                  type: object
+                                ignoreDifferences:
+                                  description: IgnoreDifferences controls resources fields which should be ignored during comparison
+                                  items:
+                                    description: ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
+                                    properties:
+                                      group:
+                                        type: string
+                                      jsonPointers:
+                                        items:
+                                          type: string
+                                        type: array
+                                      kind:
+                                        type: string
+                                      name:
+                                        type: string
+                                      namespace:
+                                        type: string
+                                    required:
+                                    - jsonPointers
+                                    - kind
+                                    type: object
+                                  type: array
+                                info:
+                                  description: Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application
+                                  items:
+                                    properties:
+                                      name:
+                                        type: string
+                                      value:
+                                        type: string
+                                    required:
+                                    - name
+                                    - value
+                                    type: object
+                                  type: array
+                                project:
+                                  description: Project is a application project name. Empty name means that application belongs to 'default' project.
+                                  type: string
+                                revisionHistoryLimit:
+                                  description: This limits this number of items kept in the apps revision history. This should only be changed in exceptional circumstances. Setting to zero will store no history. This will reduce storage used. Increasing will increase the space used to store the history, so we do not recommend increasing it. Default is 10.
+                                  format: int64
+                                  type: integer
+                                source:
+                                  description: Source is a reference to the location ksonnet application definition
+                                  properties:
+                                    chart:
+                                      description: Chart is a Helm chart name
+                                      type: string
+                                    directory:
+                                      description: Directory holds path/directory specific options
+                                      properties:
+                                        exclude:
+                                          type: string
+                                        jsonnet:
+                                          description: ApplicationSourceJsonnet holds jsonnet specific options
+                                          properties:
+                                            extVars:
+                                              description: ExtVars is a list of Jsonnet External Variables
+                                              items:
+                                                description: JsonnetVar is a jsonnet variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                            libs:
+                                              description: Additional library search dirs
+                                              items:
+                                                type: string
+                                              type: array
+                                            tlas:
+                                              description: TLAS is a list of Jsonnet Top-level Arguments
+                                              items:
+                                                description: JsonnetVar is a jsonnet variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                          type: object
+                                        recurse:
+                                          type: boolean
+                                      type: object
+                                    helm:
+                                      description: Helm holds helm specific options
+                                      properties:
+                                        fileParameters:
+                                          description: FileParameters are file parameters to the helm template
+                                          items:
+                                            description: HelmFileParameter is a file parameter to a helm template
+                                            properties:
+                                              name:
+                                                description: Name is the name of the helm parameter
+                                                type: string
+                                              path:
+                                                description: Path is the path value for the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        parameters:
+                                          description: Parameters are parameters to the helm template
+                                          items:
+                                            description: HelmParameter is a parameter to a helm template
+                                            properties:
+                                              forceString:
+                                                description: ForceString determines whether to tell Helm to interpret booleans and numbers as strings
+                                                type: boolean
+                                              name:
+                                                description: Name is the name of the helm parameter
+                                                type: string
+                                              value:
+                                                description: Value is the value for the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        releaseName:
+                                          description: The Helm release name. If omitted it will use the application name
+                                          type: string
+                                        valueFiles:
+                                          description: ValuesFiles is a list of Helm value files to use when generating a template
+                                          items:
+                                            type: string
+                                          type: array
+                                        values:
+                                          description: Values is Helm values, typically defined as a block
+                                          type: string
+                                        version:
+                                          description: Version is the Helm version to use for templating with
+                                          type: string
+                                      type: object
+                                    ksonnet:
+                                      description: Ksonnet holds ksonnet specific options
+                                      properties:
+                                        environment:
+                                          description: Environment is a ksonnet application environment name
+                                          type: string
+                                        parameters:
+                                          description: Parameters are a list of ksonnet component parameter override values
+                                          items:
+                                            description: KsonnetParameter is a ksonnet component parameter
+                                            properties:
+                                              component:
+                                                type: string
+                                              name:
+                                                type: string
+                                              value:
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                      type: object
+                                    kustomize:
+                                      description: Kustomize holds kustomize specific options
+                                      properties:
+                                        commonAnnotations:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonAnnotations adds additional kustomize commonAnnotations
+                                          type: object
+                                        commonLabels:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonLabels adds additional kustomize commonLabels
+                                          type: object
+                                        images:
+                                          description: Images are kustomize image overrides
+                                          items:
+                                            type: string
+                                          type: array
+                                        namePrefix:
+                                          description: NamePrefix is a prefix appended to resources for kustomize apps
+                                          type: string
+                                        nameSuffix:
+                                          description: NameSuffix is a suffix appended to resources for kustomize apps
+                                          type: string
+                                        version:
+                                          description: Version contains optional Kustomize version
+                                          type: string
+                                      type: object
+                                    path:
+                                      description: Path is a directory path within the Git repository
+                                      type: string
+                                    plugin:
+                                      description: ConfigManagementPlugin holds config management plugin specific options
+                                      properties:
+                                        env:
+                                          items:
+                                            properties:
+                                              name:
+                                                description: the name, usually uppercase
+                                                type: string
+                                              value:
+                                                description: the value
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                        name:
+                                          type: string
+                                      type: object
+                                    repoURL:
+                                      description: RepoURL is the repository URL of the application manifests
+                                      type: string
+                                    targetRevision:
+                                      description: TargetRevision defines the commit, tag, or branch in which to sync the application to. If omitted, will sync to HEAD
+                                      type: string
+                                  required:
+                                  - repoURL
+                                  type: object
+                                syncPolicy:
+                                  description: SyncPolicy controls when a sync will be performed
+                                  properties:
+                                    automated:
+                                      description: Automated will keep an application synced to the target revision
+                                      properties:
+                                        allowEmpty:
+                                          description: 'AllowEmpty allows apps have zero live resources (default: false)'
+                                          type: boolean
+                                        prune:
+                                          description: 'Prune will prune resources automatically as part of automated sync (default: false)'
+                                          type: boolean
+                                        selfHeal:
+                                          description: 'SelfHeal enables auto-syncing if  (default: false)'
+                                          type: boolean
+                                      type: object
+                                    retry:
+                                      description: Retry controls failed sync retry behavior
+                                      properties:
+                                        backoff:
+                                          description: Backoff is a backoff strategy
+                                          properties:
+                                            duration:
+                                              description: Duration is the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h")
+                                              type: string
+                                            factor:
+                                              description: Factor is a factor to multiply the base duration after each failed retry
+                                              format: int64
+                                              type: integer
+                                            maxDuration:
+                                              description: MaxDuration is the maximum amount of time allowed for the backoff strategy
+                                              type: string
+                                          type: object
+                                        limit:
+                                          description: Limit is the maximum number of attempts when retrying a container
+                                          format: int64
+                                          type: integer
+                                      type: object
+                                    syncOptions:
+                                      description: Options allow you to specify whole app sync-options
+                                      items:
+                                        type: string
+                                      type: array
+                                  type: object
+                              required:
+                              - destination
+                              - project
+                              - source
+                              type: object
+                          required:
+                          - metadata
+                          - spec
+                          type: object
+                      required:
+                      - elements
+                      type: object
+                    matrix:
+                      description: MatrixGenerator include Other generators
+                      properties:
+                        generators:
+                          items:
+                            description: ApplicationSetBaseGenerator include list item info CRD dosn't support recursive types so we need a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            properties:
+                              clusterDecisionResource:
+                                description: DuckType defines a generator to match against clusters registered with ArgoCD.
+                                properties:
+                                  configMapRef:
+                                    description: ConfigMapRef is a ConfigMap with the duck type definitions needed to retreive the data              this includes apiVersion(group/version), kind, matchKey and validation settings Name is the resource name of the kind, group and version, defined in the ConfigMapRef RequeueAfterSeconds is how long before the duckType will be rechecked for a change
+                                    type: string
+                                  name:
+                                    type: string
+                                  requeueAfterSeconds:
+                                    format: int64
+                                    type: integer
+                                  template:
+                                    description: ApplicationSetTemplate represents argocd ApplicationSpec
+                                    properties:
+                                      metadata:
+                                        description: ApplicationSetTemplateMeta represents the Argo CD application fields that may be used for Applications generated from the ApplicationSet (based on metav1.ObjectMeta)
+                                        properties:
+                                          annotations:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          labels:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          name:
+                                            type: string
+                                          namespace:
+                                            type: string
+                                        type: object
+                                      spec:
+                                        description: ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.
+                                        properties:
+                                          destination:
+                                            description: Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml
+                                            properties:
+                                              name:
+                                                description: Name of the destination cluster which can be used instead of server (url) field
+                                                type: string
+                                              namespace:
+                                                description: Namespace overrides the environment namespace value in the ksonnet app.yaml
+                                                type: string
+                                              server:
+                                                description: Server overrides the environment server value in the ksonnet app.yaml
+                                                type: string
+                                            type: object
+                                          ignoreDifferences:
+                                            description: IgnoreDifferences controls resources fields which should be ignored during comparison
+                                            items:
+                                              description: ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
+                                              properties:
+                                                group:
+                                                  type: string
+                                                jsonPointers:
+                                                  items:
+                                                    type: string
+                                                  type: array
+                                                kind:
+                                                  type: string
+                                                name:
+                                                  type: string
+                                                namespace:
+                                                  type: string
+                                              required:
+                                              - jsonPointers
+                                              - kind
+                                              type: object
+                                            type: array
+                                          info:
+                                            description: Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application
+                                            items:
+                                              properties:
+                                                name:
+                                                  type: string
+                                                value:
+                                                  type: string
+                                              required:
+                                              - name
+                                              - value
+                                              type: object
+                                            type: array
+                                          project:
+                                            description: Project is a application project name. Empty name means that application belongs to 'default' project.
+                                            type: string
+                                          revisionHistoryLimit:
+                                            description: This limits this number of items kept in the apps revision history. This should only be changed in exceptional circumstances. Setting to zero will store no history. This will reduce storage used. Increasing will increase the space used to store the history, so we do not recommend increasing it. Default is 10.
+                                            format: int64
+                                            type: integer
+                                          source:
+                                            description: Source is a reference to the location ksonnet application definition
+                                            properties:
+                                              chart:
+                                                description: Chart is a Helm chart name
+                                                type: string
+                                              directory:
+                                                description: Directory holds path/directory specific options
+                                                properties:
+                                                  exclude:
+                                                    type: string
+                                                  jsonnet:
+                                                    description: ApplicationSourceJsonnet holds jsonnet specific options
+                                                    properties:
+                                                      extVars:
+                                                        description: ExtVars is a list of Jsonnet External Variables
+                                                        items:
+                                                          description: JsonnetVar is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                      libs:
+                                                        description: Additional library search dirs
+                                                        items:
+                                                          type: string
+                                                        type: array
+                                                      tlas:
+                                                        description: TLAS is a list of Jsonnet Top-level Arguments
+                                                        items:
+                                                          description: JsonnetVar is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                    type: object
+                                                  recurse:
+                                                    type: boolean
+                                                type: object
+                                              helm:
+                                                description: Helm holds helm specific options
+                                                properties:
+                                                  fileParameters:
+                                                    description: FileParameters are file parameters to the helm template
+                                                    items:
+                                                      description: HelmFileParameter is a file parameter to a helm template
+                                                      properties:
+                                                        name:
+                                                          description: Name is the name of the helm parameter
+                                                          type: string
+                                                        path:
+                                                          description: Path is the path value for the helm parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  parameters:
+                                                    description: Parameters are parameters to the helm template
+                                                    items:
+                                                      description: HelmParameter is a parameter to a helm template
+                                                      properties:
+                                                        forceString:
+                                                          description: ForceString determines whether to tell Helm to interpret booleans and numbers as strings
+                                                          type: boolean
+                                                        name:
+                                                          description: Name is the name of the helm parameter
+                                                          type: string
+                                                        value:
+                                                          description: Value is the value for the helm parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  releaseName:
+                                                    description: The Helm release name. If omitted it will use the application name
+                                                    type: string
+                                                  valueFiles:
+                                                    description: ValuesFiles is a list of Helm value files to use when generating a template
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  values:
+                                                    description: Values is Helm values, typically defined as a block
+                                                    type: string
+                                                  version:
+                                                    description: Version is the Helm version to use for templating with
+                                                    type: string
+                                                type: object
+                                              ksonnet:
+                                                description: Ksonnet holds ksonnet specific options
+                                                properties:
+                                                  environment:
+                                                    description: Environment is a ksonnet application environment name
+                                                    type: string
+                                                  parameters:
+                                                    description: Parameters are a list of ksonnet component parameter override values
+                                                    items:
+                                                      description: KsonnetParameter is a ksonnet component parameter
+                                                      properties:
+                                                        component:
+                                                          type: string
+                                                        name:
+                                                          type: string
+                                                        value:
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                type: object
+                                              kustomize:
+                                                description: Kustomize holds kustomize specific options
+                                                properties:
+                                                  commonAnnotations:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonAnnotations adds additional kustomize commonAnnotations
+                                                    type: object
+                                                  commonLabels:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonLabels adds additional kustomize commonLabels
+                                                    type: object
+                                                  images:
+                                                    description: Images are kustomize image overrides
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  namePrefix:
+                                                    description: NamePrefix is a prefix appended to resources for kustomize apps
+                                                    type: string
+                                                  nameSuffix:
+                                                    description: NameSuffix is a suffix appended to resources for kustomize apps
+                                                    type: string
+                                                  version:
+                                                    description: Version contains optional Kustomize version
+                                                    type: string
+                                                type: object
+                                              path:
+                                                description: Path is a directory path within the Git repository
+                                                type: string
+                                              plugin:
+                                                description: ConfigManagementPlugin holds config management plugin specific options
+                                                properties:
+                                                  env:
+                                                    items:
+                                                      properties:
+                                                        name:
+                                                          description: the name, usually uppercase
+                                                          type: string
+                                                        value:
+                                                          description: the value
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                  name:
+                                                    type: string
+                                                type: object
+                                              repoURL:
+                                                description: RepoURL is the repository URL of the application manifests
+                                                type: string
+                                              targetRevision:
+                                                description: TargetRevision defines the commit, tag, or branch in which to sync the application to. If omitted, will sync to HEAD
+                                                type: string
+                                            required:
+                                            - repoURL
+                                            type: object
+                                          syncPolicy:
+                                            description: SyncPolicy controls when a sync will be performed
+                                            properties:
+                                              automated:
+                                                description: Automated will keep an application synced to the target revision
+                                                properties:
+                                                  allowEmpty:
+                                                    description: 'AllowEmpty allows apps have zero live resources (default: false)'
+                                                    type: boolean
+                                                  prune:
+                                                    description: 'Prune will prune resources automatically as part of automated sync (default: false)'
+                                                    type: boolean
+                                                  selfHeal:
+                                                    description: 'SelfHeal enables auto-syncing if  (default: false)'
+                                                    type: boolean
+                                                type: object
+                                              retry:
+                                                description: Retry controls failed sync retry behavior
+                                                properties:
+                                                  backoff:
+                                                    description: Backoff is a backoff strategy
+                                                    properties:
+                                                      duration:
+                                                        description: Duration is the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h")
+                                                        type: string
+                                                      factor:
+                                                        description: Factor is a factor to multiply the base duration after each failed retry
+                                                        format: int64
+                                                        type: integer
+                                                      maxDuration:
+                                                        description: MaxDuration is the maximum amount of time allowed for the backoff strategy
+                                                        type: string
+                                                    type: object
+                                                  limit:
+                                                    description: Limit is the maximum number of attempts when retrying a container
+                                                    format: int64
+                                                    type: integer
+                                                type: object
+                                              syncOptions:
+                                                description: Options allow you to specify whole app sync-options
+                                                items:
+                                                  type: string
+                                                type: array
+                                            type: object
+                                        required:
+                                        - destination
+                                        - project
+                                        - source
+                                        type: object
+                                    required:
+                                    - metadata
+                                    - spec
+                                    type: object
+                                  values:
+                                    additionalProperties:
+                                      type: string
+                                    description: Values contains key/value pairs which are passed directly as parameters to the template
+                                    type: object
+                                required:
+                                - configMapRef
+                                - name
+                                type: object
                               clusters:
                                 description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
                                 properties:
@@ -6185,7 +6855,7 @@ spec:
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
-        image: argoprojlabs/argocd-applicationset:latest
+        image: quay.io/argoproj/argocd-applicationset:latest
         imagePullPolicy: Always
         name: argocd-applicationset-controller
         volumeMounts:
diff --git a/manifests/install.yaml b/manifests/install.yaml
index 1342152..a5a2ad8 100644
--- a/manifests/install.yaml
+++ b/manifests/install.yaml
@@ -38,39 +38,17 @@ spec:
                 items:
                   description: ApplicationSetGenerator include list item info
                   properties:
-                    clusters:
-                      description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
+                    clusterDecisionResource:
+                      description: DuckType defines a generator to match against clusters registered with ArgoCD.
                       properties:
-                        selector:
-                          description: Selector defines a label selector to match against all clusters registered with ArgoCD. Clusters today are stored as Kubernetes Secrets, thus the Secret labels will be used for matching the selector.
-                          properties:
-                            matchExpressions:
-                              description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
-                              items:
-                                description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
-                                properties:
-                                  key:
-                                    description: key is the label key that the selector applies to.
-                                    type: string
-                                  operator:
-                                    description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
-                                    type: string
-                                  values:
-                                    description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
-                                    items:
-                                      type: string
-                                    type: array
-                                required:
-                                - key
-                                - operator
-                                type: object
-                              type: array
-                            matchLabels:
-                              additionalProperties:
-                                type: string
-                              description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
-                              type: object
-                          type: object
+                        configMapRef:
+                          description: ConfigMapRef is a ConfigMap with the duck type definitions needed to retreive the data              this includes apiVersion(group/version), kind, matchKey and validation settings Name is the resource name of the kind, group and version, defined in the ConfigMapRef RequeueAfterSeconds is how long before the duckType will be rechecked for a change
+                          type: string
+                        name:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -391,36 +369,43 @@ spec:
                             type: string
                           description: Values contains key/value pairs which are passed directly as parameters to the template
                           type: object
+                      required:
+                      - configMapRef
+                      - name
                       type: object
-                    git:
+                    clusters:
+                      description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
                       properties:
-                        directories:
-                          items:
-                            properties:
-                              exclude:
-                                type: boolean
-                              path:
-                                type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        files:
-                          items:
-                            properties:
-                              path:
+                        selector:
+                          description: Selector defines a label selector to match against all clusters registered with ArgoCD. Clusters today are stored as Kubernetes Secrets, thus the Secret labels will be used for matching the selector.
+                          properties:
+                            matchExpressions:
+                              description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
+                              items:
+                                description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
+                                properties:
+                                  key:
+                                    description: key is the label key that the selector applies to.
+                                    type: string
+                                  operator:
+                                    description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
+                                    type: string
+                                  values:
+                                    description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
+                                    items:
+                                      type: string
+                                    type: array
+                                required:
+                                - key
+                                - operator
+                                type: object
+                              type: array
+                            matchLabels:
+                              additionalProperties:
                                 type: string
-                            required:
-                            - path
-                            type: object
-                          type: array
-                        repoURL:
-                          type: string
-                        requeueAfterSeconds:
-                          format: int64
-                          type: integer
-                        revision:
-                          type: string
+                              description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
+                              type: object
+                          type: object
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -736,31 +721,41 @@ spec:
                           - metadata
                           - spec
                           type: object
-                      required:
-                      - repoURL
-                      - revision
+                        values:
+                          additionalProperties:
+                            type: string
+                          description: Values contains key/value pairs which are passed directly as parameters to the template
+                          type: object
                       type: object
-                    list:
-                      description: ListGenerator include items info
+                    git:
                       properties:
-                        elements:
+                        directories:
                           items:
-                            description: ListGeneratorElement include cluster and url info
                             properties:
-                              cluster:
+                              exclude:
+                                type: boolean
+                              path:
                                 type: string
-                              url:
+                            required:
+                            - path
+                            type: object
+                          type: array
+                        files:
+                          items:
+                            properties:
+                              path:
                                 type: string
-                              values:
-                                additionalProperties:
-                                  type: string
-                                description: Values contains key/value pairs which are passed directly as parameters to the template
-                                type: object
                             required:
-                            - cluster
-                            - url
+                            - path
                             type: object
                           type: array
+                        repoURL:
+                          type: string
+                        requeueAfterSeconds:
+                          format: int64
+                          type: integer
+                        revision:
+                          type: string
                         template:
                           description: ApplicationSetTemplate represents argocd ApplicationSpec
                           properties:
@@ -1077,15 +1072,690 @@ spec:
                           - spec
                           type: object
                       required:
-                      - elements
+                      - repoURL
+                      - revision
                       type: object
-                    matrix:
-                      description: MatrixGenerator include Other generators
+                    list:
+                      description: ListGenerator include items info
                       properties:
-                        generators:
+                        elements:
                           items:
-                            description: ApplicationSetBaseGenerator include list item info CRD dosn't support recursive types so we need a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            description: ListGeneratorElement include cluster and url info
                             properties:
+                              cluster:
+                                type: string
+                              url:
+                                type: string
+                              values:
+                                additionalProperties:
+                                  type: string
+                                description: Values contains key/value pairs which are passed directly as parameters to the template
+                                type: object
+                            required:
+                            - cluster
+                            - url
+                            type: object
+                          type: array
+                        template:
+                          description: ApplicationSetTemplate represents argocd ApplicationSpec
+                          properties:
+                            metadata:
+                              description: ApplicationSetTemplateMeta represents the Argo CD application fields that may be used for Applications generated from the ApplicationSet (based on metav1.ObjectMeta)
+                              properties:
+                                annotations:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                labels:
+                                  additionalProperties:
+                                    type: string
+                                  type: object
+                                name:
+                                  type: string
+                                namespace:
+                                  type: string
+                              type: object
+                            spec:
+                              description: ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.
+                              properties:
+                                destination:
+                                  description: Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml
+                                  properties:
+                                    name:
+                                      description: Name of the destination cluster which can be used instead of server (url) field
+                                      type: string
+                                    namespace:
+                                      description: Namespace overrides the environment namespace value in the ksonnet app.yaml
+                                      type: string
+                                    server:
+                                      description: Server overrides the environment server value in the ksonnet app.yaml
+                                      type: string
+                                  type: object
+                                ignoreDifferences:
+                                  description: IgnoreDifferences controls resources fields which should be ignored during comparison
+                                  items:
+                                    description: ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
+                                    properties:
+                                      group:
+                                        type: string
+                                      jsonPointers:
+                                        items:
+                                          type: string
+                                        type: array
+                                      kind:
+                                        type: string
+                                      name:
+                                        type: string
+                                      namespace:
+                                        type: string
+                                    required:
+                                    - jsonPointers
+                                    - kind
+                                    type: object
+                                  type: array
+                                info:
+                                  description: Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application
+                                  items:
+                                    properties:
+                                      name:
+                                        type: string
+                                      value:
+                                        type: string
+                                    required:
+                                    - name
+                                    - value
+                                    type: object
+                                  type: array
+                                project:
+                                  description: Project is a application project name. Empty name means that application belongs to 'default' project.
+                                  type: string
+                                revisionHistoryLimit:
+                                  description: This limits this number of items kept in the apps revision history. This should only be changed in exceptional circumstances. Setting to zero will store no history. This will reduce storage used. Increasing will increase the space used to store the history, so we do not recommend increasing it. Default is 10.
+                                  format: int64
+                                  type: integer
+                                source:
+                                  description: Source is a reference to the location ksonnet application definition
+                                  properties:
+                                    chart:
+                                      description: Chart is a Helm chart name
+                                      type: string
+                                    directory:
+                                      description: Directory holds path/directory specific options
+                                      properties:
+                                        exclude:
+                                          type: string
+                                        jsonnet:
+                                          description: ApplicationSourceJsonnet holds jsonnet specific options
+                                          properties:
+                                            extVars:
+                                              description: ExtVars is a list of Jsonnet External Variables
+                                              items:
+                                                description: JsonnetVar is a jsonnet variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                            libs:
+                                              description: Additional library search dirs
+                                              items:
+                                                type: string
+                                              type: array
+                                            tlas:
+                                              description: TLAS is a list of Jsonnet Top-level Arguments
+                                              items:
+                                                description: JsonnetVar is a jsonnet variable
+                                                properties:
+                                                  code:
+                                                    type: boolean
+                                                  name:
+                                                    type: string
+                                                  value:
+                                                    type: string
+                                                required:
+                                                - name
+                                                - value
+                                                type: object
+                                              type: array
+                                          type: object
+                                        recurse:
+                                          type: boolean
+                                      type: object
+                                    helm:
+                                      description: Helm holds helm specific options
+                                      properties:
+                                        fileParameters:
+                                          description: FileParameters are file parameters to the helm template
+                                          items:
+                                            description: HelmFileParameter is a file parameter to a helm template
+                                            properties:
+                                              name:
+                                                description: Name is the name of the helm parameter
+                                                type: string
+                                              path:
+                                                description: Path is the path value for the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        parameters:
+                                          description: Parameters are parameters to the helm template
+                                          items:
+                                            description: HelmParameter is a parameter to a helm template
+                                            properties:
+                                              forceString:
+                                                description: ForceString determines whether to tell Helm to interpret booleans and numbers as strings
+                                                type: boolean
+                                              name:
+                                                description: Name is the name of the helm parameter
+                                                type: string
+                                              value:
+                                                description: Value is the value for the helm parameter
+                                                type: string
+                                            type: object
+                                          type: array
+                                        releaseName:
+                                          description: The Helm release name. If omitted it will use the application name
+                                          type: string
+                                        valueFiles:
+                                          description: ValuesFiles is a list of Helm value files to use when generating a template
+                                          items:
+                                            type: string
+                                          type: array
+                                        values:
+                                          description: Values is Helm values, typically defined as a block
+                                          type: string
+                                        version:
+                                          description: Version is the Helm version to use for templating with
+                                          type: string
+                                      type: object
+                                    ksonnet:
+                                      description: Ksonnet holds ksonnet specific options
+                                      properties:
+                                        environment:
+                                          description: Environment is a ksonnet application environment name
+                                          type: string
+                                        parameters:
+                                          description: Parameters are a list of ksonnet component parameter override values
+                                          items:
+                                            description: KsonnetParameter is a ksonnet component parameter
+                                            properties:
+                                              component:
+                                                type: string
+                                              name:
+                                                type: string
+                                              value:
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                      type: object
+                                    kustomize:
+                                      description: Kustomize holds kustomize specific options
+                                      properties:
+                                        commonAnnotations:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonAnnotations adds additional kustomize commonAnnotations
+                                          type: object
+                                        commonLabels:
+                                          additionalProperties:
+                                            type: string
+                                          description: CommonLabels adds additional kustomize commonLabels
+                                          type: object
+                                        images:
+                                          description: Images are kustomize image overrides
+                                          items:
+                                            type: string
+                                          type: array
+                                        namePrefix:
+                                          description: NamePrefix is a prefix appended to resources for kustomize apps
+                                          type: string
+                                        nameSuffix:
+                                          description: NameSuffix is a suffix appended to resources for kustomize apps
+                                          type: string
+                                        version:
+                                          description: Version contains optional Kustomize version
+                                          type: string
+                                      type: object
+                                    path:
+                                      description: Path is a directory path within the Git repository
+                                      type: string
+                                    plugin:
+                                      description: ConfigManagementPlugin holds config management plugin specific options
+                                      properties:
+                                        env:
+                                          items:
+                                            properties:
+                                              name:
+                                                description: the name, usually uppercase
+                                                type: string
+                                              value:
+                                                description: the value
+                                                type: string
+                                            required:
+                                            - name
+                                            - value
+                                            type: object
+                                          type: array
+                                        name:
+                                          type: string
+                                      type: object
+                                    repoURL:
+                                      description: RepoURL is the repository URL of the application manifests
+                                      type: string
+                                    targetRevision:
+                                      description: TargetRevision defines the commit, tag, or branch in which to sync the application to. If omitted, will sync to HEAD
+                                      type: string
+                                  required:
+                                  - repoURL
+                                  type: object
+                                syncPolicy:
+                                  description: SyncPolicy controls when a sync will be performed
+                                  properties:
+                                    automated:
+                                      description: Automated will keep an application synced to the target revision
+                                      properties:
+                                        allowEmpty:
+                                          description: 'AllowEmpty allows apps have zero live resources (default: false)'
+                                          type: boolean
+                                        prune:
+                                          description: 'Prune will prune resources automatically as part of automated sync (default: false)'
+                                          type: boolean
+                                        selfHeal:
+                                          description: 'SelfHeal enables auto-syncing if  (default: false)'
+                                          type: boolean
+                                      type: object
+                                    retry:
+                                      description: Retry controls failed sync retry behavior
+                                      properties:
+                                        backoff:
+                                          description: Backoff is a backoff strategy
+                                          properties:
+                                            duration:
+                                              description: Duration is the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h")
+                                              type: string
+                                            factor:
+                                              description: Factor is a factor to multiply the base duration after each failed retry
+                                              format: int64
+                                              type: integer
+                                            maxDuration:
+                                              description: MaxDuration is the maximum amount of time allowed for the backoff strategy
+                                              type: string
+                                          type: object
+                                        limit:
+                                          description: Limit is the maximum number of attempts when retrying a container
+                                          format: int64
+                                          type: integer
+                                      type: object
+                                    syncOptions:
+                                      description: Options allow you to specify whole app sync-options
+                                      items:
+                                        type: string
+                                      type: array
+                                  type: object
+                              required:
+                              - destination
+                              - project
+                              - source
+                              type: object
+                          required:
+                          - metadata
+                          - spec
+                          type: object
+                      required:
+                      - elements
+                      type: object
+                    matrix:
+                      description: MatrixGenerator include Other generators
+                      properties:
+                        generators:
+                          items:
+                            description: ApplicationSetBaseGenerator include list item info CRD dosn't support recursive types so we need a different type for the matrix generator https://github.com/kubernetes-sigs/controller-tools/issues/477
+                            properties:
+                              clusterDecisionResource:
+                                description: DuckType defines a generator to match against clusters registered with ArgoCD.
+                                properties:
+                                  configMapRef:
+                                    description: ConfigMapRef is a ConfigMap with the duck type definitions needed to retreive the data              this includes apiVersion(group/version), kind, matchKey and validation settings Name is the resource name of the kind, group and version, defined in the ConfigMapRef RequeueAfterSeconds is how long before the duckType will be rechecked for a change
+                                    type: string
+                                  name:
+                                    type: string
+                                  requeueAfterSeconds:
+                                    format: int64
+                                    type: integer
+                                  template:
+                                    description: ApplicationSetTemplate represents argocd ApplicationSpec
+                                    properties:
+                                      metadata:
+                                        description: ApplicationSetTemplateMeta represents the Argo CD application fields that may be used for Applications generated from the ApplicationSet (based on metav1.ObjectMeta)
+                                        properties:
+                                          annotations:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          labels:
+                                            additionalProperties:
+                                              type: string
+                                            type: object
+                                          name:
+                                            type: string
+                                          namespace:
+                                            type: string
+                                        type: object
+                                      spec:
+                                        description: ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.
+                                        properties:
+                                          destination:
+                                            description: Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml
+                                            properties:
+                                              name:
+                                                description: Name of the destination cluster which can be used instead of server (url) field
+                                                type: string
+                                              namespace:
+                                                description: Namespace overrides the environment namespace value in the ksonnet app.yaml
+                                                type: string
+                                              server:
+                                                description: Server overrides the environment server value in the ksonnet app.yaml
+                                                type: string
+                                            type: object
+                                          ignoreDifferences:
+                                            description: IgnoreDifferences controls resources fields which should be ignored during comparison
+                                            items:
+                                              description: ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
+                                              properties:
+                                                group:
+                                                  type: string
+                                                jsonPointers:
+                                                  items:
+                                                    type: string
+                                                  type: array
+                                                kind:
+                                                  type: string
+                                                name:
+                                                  type: string
+                                                namespace:
+                                                  type: string
+                                              required:
+                                              - jsonPointers
+                                              - kind
+                                              type: object
+                                            type: array
+                                          info:
+                                            description: Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application
+                                            items:
+                                              properties:
+                                                name:
+                                                  type: string
+                                                value:
+                                                  type: string
+                                              required:
+                                              - name
+                                              - value
+                                              type: object
+                                            type: array
+                                          project:
+                                            description: Project is a application project name. Empty name means that application belongs to 'default' project.
+                                            type: string
+                                          revisionHistoryLimit:
+                                            description: This limits this number of items kept in the apps revision history. This should only be changed in exceptional circumstances. Setting to zero will store no history. This will reduce storage used. Increasing will increase the space used to store the history, so we do not recommend increasing it. Default is 10.
+                                            format: int64
+                                            type: integer
+                                          source:
+                                            description: Source is a reference to the location ksonnet application definition
+                                            properties:
+                                              chart:
+                                                description: Chart is a Helm chart name
+                                                type: string
+                                              directory:
+                                                description: Directory holds path/directory specific options
+                                                properties:
+                                                  exclude:
+                                                    type: string
+                                                  jsonnet:
+                                                    description: ApplicationSourceJsonnet holds jsonnet specific options
+                                                    properties:
+                                                      extVars:
+                                                        description: ExtVars is a list of Jsonnet External Variables
+                                                        items:
+                                                          description: JsonnetVar is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                      libs:
+                                                        description: Additional library search dirs
+                                                        items:
+                                                          type: string
+                                                        type: array
+                                                      tlas:
+                                                        description: TLAS is a list of Jsonnet Top-level Arguments
+                                                        items:
+                                                          description: JsonnetVar is a jsonnet variable
+                                                          properties:
+                                                            code:
+                                                              type: boolean
+                                                            name:
+                                                              type: string
+                                                            value:
+                                                              type: string
+                                                          required:
+                                                          - name
+                                                          - value
+                                                          type: object
+                                                        type: array
+                                                    type: object
+                                                  recurse:
+                                                    type: boolean
+                                                type: object
+                                              helm:
+                                                description: Helm holds helm specific options
+                                                properties:
+                                                  fileParameters:
+                                                    description: FileParameters are file parameters to the helm template
+                                                    items:
+                                                      description: HelmFileParameter is a file parameter to a helm template
+                                                      properties:
+                                                        name:
+                                                          description: Name is the name of the helm parameter
+                                                          type: string
+                                                        path:
+                                                          description: Path is the path value for the helm parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  parameters:
+                                                    description: Parameters are parameters to the helm template
+                                                    items:
+                                                      description: HelmParameter is a parameter to a helm template
+                                                      properties:
+                                                        forceString:
+                                                          description: ForceString determines whether to tell Helm to interpret booleans and numbers as strings
+                                                          type: boolean
+                                                        name:
+                                                          description: Name is the name of the helm parameter
+                                                          type: string
+                                                        value:
+                                                          description: Value is the value for the helm parameter
+                                                          type: string
+                                                      type: object
+                                                    type: array
+                                                  releaseName:
+                                                    description: The Helm release name. If omitted it will use the application name
+                                                    type: string
+                                                  valueFiles:
+                                                    description: ValuesFiles is a list of Helm value files to use when generating a template
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  values:
+                                                    description: Values is Helm values, typically defined as a block
+                                                    type: string
+                                                  version:
+                                                    description: Version is the Helm version to use for templating with
+                                                    type: string
+                                                type: object
+                                              ksonnet:
+                                                description: Ksonnet holds ksonnet specific options
+                                                properties:
+                                                  environment:
+                                                    description: Environment is a ksonnet application environment name
+                                                    type: string
+                                                  parameters:
+                                                    description: Parameters are a list of ksonnet component parameter override values
+                                                    items:
+                                                      description: KsonnetParameter is a ksonnet component parameter
+                                                      properties:
+                                                        component:
+                                                          type: string
+                                                        name:
+                                                          type: string
+                                                        value:
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                type: object
+                                              kustomize:
+                                                description: Kustomize holds kustomize specific options
+                                                properties:
+                                                  commonAnnotations:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonAnnotations adds additional kustomize commonAnnotations
+                                                    type: object
+                                                  commonLabels:
+                                                    additionalProperties:
+                                                      type: string
+                                                    description: CommonLabels adds additional kustomize commonLabels
+                                                    type: object
+                                                  images:
+                                                    description: Images are kustomize image overrides
+                                                    items:
+                                                      type: string
+                                                    type: array
+                                                  namePrefix:
+                                                    description: NamePrefix is a prefix appended to resources for kustomize apps
+                                                    type: string
+                                                  nameSuffix:
+                                                    description: NameSuffix is a suffix appended to resources for kustomize apps
+                                                    type: string
+                                                  version:
+                                                    description: Version contains optional Kustomize version
+                                                    type: string
+                                                type: object
+                                              path:
+                                                description: Path is a directory path within the Git repository
+                                                type: string
+                                              plugin:
+                                                description: ConfigManagementPlugin holds config management plugin specific options
+                                                properties:
+                                                  env:
+                                                    items:
+                                                      properties:
+                                                        name:
+                                                          description: the name, usually uppercase
+                                                          type: string
+                                                        value:
+                                                          description: the value
+                                                          type: string
+                                                      required:
+                                                      - name
+                                                      - value
+                                                      type: object
+                                                    type: array
+                                                  name:
+                                                    type: string
+                                                type: object
+                                              repoURL:
+                                                description: RepoURL is the repository URL of the application manifests
+                                                type: string
+                                              targetRevision:
+                                                description: TargetRevision defines the commit, tag, or branch in which to sync the application to. If omitted, will sync to HEAD
+                                                type: string
+                                            required:
+                                            - repoURL
+                                            type: object
+                                          syncPolicy:
+                                            description: SyncPolicy controls when a sync will be performed
+                                            properties:
+                                              automated:
+                                                description: Automated will keep an application synced to the target revision
+                                                properties:
+                                                  allowEmpty:
+                                                    description: 'AllowEmpty allows apps have zero live resources (default: false)'
+                                                    type: boolean
+                                                  prune:
+                                                    description: 'Prune will prune resources automatically as part of automated sync (default: false)'
+                                                    type: boolean
+                                                  selfHeal:
+                                                    description: 'SelfHeal enables auto-syncing if  (default: false)'
+                                                    type: boolean
+                                                type: object
+                                              retry:
+                                                description: Retry controls failed sync retry behavior
+                                                properties:
+                                                  backoff:
+                                                    description: Backoff is a backoff strategy
+                                                    properties:
+                                                      duration:
+                                                        description: Duration is the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h")
+                                                        type: string
+                                                      factor:
+                                                        description: Factor is a factor to multiply the base duration after each failed retry
+                                                        format: int64
+                                                        type: integer
+                                                      maxDuration:
+                                                        description: MaxDuration is the maximum amount of time allowed for the backoff strategy
+                                                        type: string
+                                                    type: object
+                                                  limit:
+                                                    description: Limit is the maximum number of attempts when retrying a container
+                                                    format: int64
+                                                    type: integer
+                                                type: object
+                                              syncOptions:
+                                                description: Options allow you to specify whole app sync-options
+                                                items:
+                                                  type: string
+                                                type: array
+                                            type: object
+                                        required:
+                                        - destination
+                                        - project
+                                        - source
+                                        type: object
+                                    required:
+                                    - metadata
+                                    - spec
+                                    type: object
+                                  values:
+                                    additionalProperties:
+                                      type: string
+                                    description: Values contains key/value pairs which are passed directly as parameters to the template
+                                    type: object
+                                required:
+                                - configMapRef
+                                - name
+                                type: object
                               clusters:
                                 description: ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
                                 properties:
@@ -3658,7 +4328,7 @@ spec:
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
-        image: argoprojlabs/argocd-applicationset:latest
+        image: quay.io/argoproj/argocd-applicationset:latest
         imagePullPolicy: Always
         name: argocd-applicationset-controller
         volumeMounts:
diff --git a/pkg/controllers/applicationset_controller.go b/pkg/controllers/applicationset_controller.go
index 9b12b0c..92dee9b 100644
--- a/pkg/controllers/applicationset_controller.go
+++ b/pkg/controllers/applicationset_controller.go
@@ -188,9 +188,9 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argopr
 	var res time.Duration
 	for _, requestedGenerator := range applicationSetInfo.Spec.Generators {
 
-		generators := generators.GetRelevantGenerators(&requestedGenerator, r.Generators)
+		relevantGenerators := generators.GetRelevantGenerators(&requestedGenerator, r.Generators)
 
-		for _, g := range generators {
+		for _, g := range relevantGenerators {
 			t := g.GetRequeueAfter(&requestedGenerator)
 
 			if res == 0 {
@@ -445,7 +445,7 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte
 	if err := utils.ValidateDestination(ctx, &app.Spec.Destination, r.KubeClientset, applicationSet.Namespace); err != nil {
 
 		// Filter out the Argo CD finalizer from the finalizer list
-		newFinalizers := []string{}
+		var newFinalizers []string
 		for _, existingFinalizer := range app.Finalizers {
 			if existingFinalizer != common.ResourcesFinalizerName { // only remove this one
 				newFinalizers = append(newFinalizers, existingFinalizer)
diff --git a/pkg/generators/cluster.go b/pkg/generators/cluster.go
index 1e9f9ad..334e450 100644
--- a/pkg/generators/cluster.go
+++ b/pkg/generators/cluster.go
@@ -3,6 +3,8 @@ package generators
 import (
 	"context"
 	"fmt"
+	"regexp"
+	"strings"
 	"time"
 
 	"github.com/argoproj/argo-cd/util/settings"
@@ -116,7 +118,7 @@ func (g *ClusterGenerator) GenerateParams(
 	// For each matching cluster secret (non-local clusters only)
 	for _, cluster := range secretsFound {
 		params := map[string]string{}
-		params["name"] = string(cluster.Data["name"])
+		params["name"] = sanitizeName(string(cluster.Data["name"]))
 		params["server"] = string(cluster.Data["server"])
 		for key, value := range cluster.ObjectMeta.Annotations {
 			params[fmt.Sprintf("metadata.annotations.%s", key)] = value
@@ -161,3 +163,20 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoprojiov1
 	return res, nil
 
 }
+
+// santize the name in accordance with the below rules
+// 1. contain no more than 253 characters
+// 2. contain only lowercase alphanumeric characters, '-' or '.'
+// 3. start and end with an alphanumeric character
+func sanitizeName(name string) string {
+	invalidDNSNameChars := regexp.MustCompile("[^-a-z0-9.]")
+	maxDNSNameLength := 253
+
+	name = strings.ToLower(name)
+	name = invalidDNSNameChars.ReplaceAllString(name, "-")
+	if len(name) > maxDNSNameLength {
+		name = name[:maxDNSNameLength]
+	}
+
+	return strings.Trim(name, "-.")
+}
diff --git a/pkg/generators/duck_type.go b/pkg/generators/duck_type.go
new file mode 100644
index 0000000..8d9f654
--- /dev/null
+++ b/pkg/generators/duck_type.go
@@ -0,0 +1,189 @@
+package generators
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/argoproj/argo-cd/util/settings"
+	log "github.com/sirupsen/logrus"
+
+	argoprojiov1alpha1 "github.com/argoproj-labs/applicationset/api/v1alpha1"
+	"github.com/argoproj-labs/applicationset/pkg/utils"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/client-go/dynamic"
+	"k8s.io/client-go/kubernetes"
+)
+
+var _ Generator = (*DuckTypeGenerator)(nil)
+
+// DuckTypeGenerator generates Applications for some or all clusters registered with ArgoCD.
+type DuckTypeGenerator struct {
+	ctx             context.Context
+	dynClient       dynamic.Interface
+	clientset       kubernetes.Interface
+	namespace       string // namespace is the Argo CD namespace
+	settingsManager *settings.SettingsManager
+}
+
+func NewDuckTypeGenerator(ctx context.Context, dynClient dynamic.Interface, clientset kubernetes.Interface, namespace string) Generator {
+
+	settingsManager := settings.NewSettingsManager(ctx, clientset, namespace)
+
+	g := &DuckTypeGenerator{
+		ctx:             ctx,
+		dynClient:       dynClient,
+		clientset:       clientset,
+		namespace:       namespace,
+		settingsManager: settingsManager,
+	}
+	return g
+}
+
+func (g *DuckTypeGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration {
+
+	// Return a requeue default of 3 minutes, if no override is specified.
+
+	if appSetGenerator.ClusterDecisionResource.RequeueAfterSeconds != nil {
+		return time.Duration(*appSetGenerator.ClusterDecisionResource.RequeueAfterSeconds) * time.Second
+	}
+
+	return DefaultRequeueAfterSeconds
+}
+
+func (g *DuckTypeGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate {
+	return &appSetGenerator.ClusterDecisionResource.Template
+}
+
+func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, _ *argoprojiov1alpha1.ApplicationSet) ([]map[string]string, error) {
+
+	if appSetGenerator == nil {
+		return nil, EmptyAppSetGeneratorError
+	}
+
+	// Not likely to happen
+	if appSetGenerator.ClusterDecisionResource == nil {
+		return nil, nil
+	}
+
+	// ListCluster from Argo CD's util/db package will include the local cluster in the list of clusters
+	clustersFromArgoCD, err := utils.ListClusters(g.ctx, g.clientset, g.namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	if clustersFromArgoCD == nil {
+		return nil, nil
+	}
+
+	// Read the configMapRef
+	cm, err := g.clientset.CoreV1().ConfigMaps(g.namespace).Get(g.ctx, appSetGenerator.ClusterDecisionResource.ConfigMapRef, metav1.GetOptions{})
+
+	if err != nil {
+		return nil, err
+	}
+
+	// Extract GVK data for the dynamic client to use
+	versionIdx := strings.Index(cm.Data["apiVersion"], "/")
+	kind := cm.Data["kind"]
+	resourceName := appSetGenerator.ClusterDecisionResource.Name
+
+	log.WithField("resourcename.kind.apiVersion", resourceName+"."+kind+"."+
+		cm.Data["apiVersion"]).Info("ResourceName.Kind.Group/Version Reference")
+
+	if kind == "" || resourceName == "" || versionIdx < 1 {
+		log.Warningf("kind=%v, resourceName=%v, versionIdx=%v", kind, resourceName, versionIdx)
+		return nil, errors.New("There is a problem with the apiVersion, kind or resourceName provided")
+	}
+
+	// Split up the apiVersion
+	group := cm.Data["apiVersion"][0:versionIdx]
+	version := cm.Data["apiVersion"][versionIdx+1:]
+	log.WithField("kind.group.version", kind+"."+group+"/"+version).Debug("decoded Ref")
+
+	duckGVR := schema.GroupVersionResource{Group: group, Version: version, Resource: kind}
+	duckResource, err := g.dynClient.Resource(duckGVR).Namespace(g.namespace).Get(g.ctx, resourceName, metav1.GetOptions{})
+
+	if err != nil {
+		log.WithField("GVK", duckGVR).Warningf("resource was not found with name=%v", resourceName)
+		return nil, err
+	}
+
+	if duckResource == nil || duckResource.Object["status"] == nil {
+		log.Warning("duck type status missing")
+		return nil, nil
+	}
+
+	log.WithField("duckResourceName", duckResource.GetName()).Debug("found duck status on resource")
+
+	// Override the duck type in the status of the resource
+	statusListKey := "clusters"
+
+	matchKey := cm.Data["matchKey"]
+
+	if cm.Data["statusListKey"] != "" {
+		statusListKey = cm.Data["statusListKey"]
+	}
+	if matchKey == "" {
+		log.WithField("matchKey", matchKey).Warning("matchKey not found in " + cm.Name)
+		return nil, nil
+
+	}
+
+	res := []map[string]string{}
+
+	clusterDecisions := duckResource.Object["status"].(map[string]interface{})[statusListKey]
+
+	if clusterDecisions != nil {
+		for _, cluster := range clusterDecisions.([]interface{}) {
+
+			// generated instance of cluster params
+			params := map[string]string{}
+
+			matchValue := cluster.(map[string]interface{})[matchKey]
+			if matchValue == nil || matchValue.(string) == "" {
+				log.Warningf("matchKey=%v not found in \"%v\" list: %v\n", matchKey, statusListKey, cluster.(map[string]interface{}))
+				continue
+			}
+
+			strMatchValue := matchValue.(string)
+			log.WithField(matchKey, strMatchValue).Debug("validate against ArgoCD")
+
+			found := false
+
+			for _, argoCluster := range clustersFromArgoCD.Items {
+				if argoCluster.Name == strMatchValue {
+
+					log.WithField(matchKey, argoCluster.Name).Info("matched cluster in ArgoCD")
+					params["name"] = argoCluster.Name
+					params["server"] = argoCluster.Server
+
+					found = true
+				}
+
+			}
+
+			if !found {
+				log.WithField(matchKey, strMatchValue).Warning("unmatched cluster in ArgoCD")
+				continue
+			}
+
+			for key, value := range cluster.(map[string]interface{}) {
+				params[key] = value.(string)
+			}
+
+			for key, value := range appSetGenerator.ClusterDecisionResource.Values {
+				params[fmt.Sprintf("values.%s", key)] = value
+			}
+
+			res = append(res, params)
+		}
+	} else {
+		return nil, errors.New("duck type status." + statusListKey + " missing")
+	}
+
+	return res, nil
+}
diff --git a/pkg/generators/git.go b/pkg/generators/git.go
index 32d5cb9..ea14b43 100644
--- a/pkg/generators/git.go
+++ b/pkg/generators/git.go
@@ -16,10 +16,6 @@ import (
 
 var _ Generator = (*GitGenerator)(nil)
 
-const (
-	DefaultRequeueAfterSeconds = 3 * time.Minute
-)
-
 type GitGenerator struct {
 	repos services.Repos
 }
diff --git a/pkg/generators/interface.go b/pkg/generators/interface.go
index 3d9ff11..326dfef 100644
--- a/pkg/generators/interface.go
+++ b/pkg/generators/interface.go
@@ -25,3 +25,8 @@ type Generator interface {
 
 var EmptyAppSetGeneratorError = errors.New("ApplicationSet is empty")
 var NoRequeueAfter time.Duration
+
+// DefaultRequeueAfterSeconds is used when GetRequeueAfter is not specified, it is the default time to wait before the next reconcile loop
+const (
+	DefaultRequeueAfterSeconds = 3 * time.Minute
+)
diff --git a/pkg/services/repo_service.go b/pkg/services/repo_service.go
index eded55e..71a49af 100644
--- a/pkg/services/repo_service.go
+++ b/pkg/services/repo_service.go
@@ -2,7 +2,6 @@ package services
 
 import (
 	"context"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -141,7 +140,7 @@ func (a *argoCDService) GetFileContent(ctx context.Context, repoURL string, revi
 		return nil, err
 	}
 
-	bytes, err := ioutil.ReadFile(filepath.Join(gitRepoClient.Root(), path))
+	bytes, err := os.ReadFile(filepath.Join(gitRepoClient.Root(), path))
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/pkg/generators/cluster_test.go b/pkg/generators/cluster_test.go
index 6bec3f8..ca441d3 100644
--- a/pkg/generators/cluster_test.go
+++ b/pkg/generators/cluster_test.go
@@ -241,3 +241,13 @@ func TestGenerateParams(t *testing.T) {
 		})
 	}
 }
+
+func TestSanitizeClusterName(t *testing.T) {
+	t.Run("valid DNS-1123 subdomain name", func(t *testing.T) {
+		assert.Equal(t, "cluster-name", sanitizeName("cluster-name"))
+	})
+	t.Run("invalid DNS-1123 subdomain name", func(t *testing.T) {
+		invalidName := "-.--CLUSTER/name  -./.-"
+		assert.Equal(t, "cluster-name", sanitizeName(invalidName))
+	})
+}
diff --git a/pkg/generators/duck_type_test.go b/pkg/generators/duck_type_test.go
new file mode 100644
index 0000000..bd5a544
--- /dev/null
+++ b/pkg/generators/duck_type_test.go
@@ -0,0 +1,248 @@
+package generators
+
+import (
+	"context"
+	"errors"
+
+	argoprojiov1alpha1 "github.com/argoproj-labs/applicationset/api/v1alpha1"
+	"github.com/stretchr/testify/assert"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
+	dynfake "k8s.io/client-go/dynamic/fake"
+	kubefake "k8s.io/client-go/kubernetes/fake"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	"testing"
+)
+
+const resourceApiVersion = "mallard.io/v1"
+const resourceKind = "ducks"
+const resourceName = "quak"
+
+func TestGenerateParamsForDuckType(t *testing.T) {
+	clusters := []client.Object{
+		&corev1.Secret{
+			TypeMeta: metav1.TypeMeta{
+				Kind:       "Secret",
+				APIVersion: "v1",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "staging-01",
+				Namespace: "namespace",
+				Labels: map[string]string{
+					"argocd.argoproj.io/secret-type": "cluster",
+					"environment":                    "staging",
+					"org":                            "foo",
+				},
+				Annotations: map[string]string{
+					"foo.argoproj.io": "staging",
+				},
+			},
+			Data: map[string][]byte{
+				"config": []byte("{}"),
+				"name":   []byte("staging-01"),
+				"server": []byte("https://staging-01.example.com"),
+			},
+			Type: corev1.SecretType("Opaque"),
+		},
+		&corev1.Secret{
+			TypeMeta: metav1.TypeMeta{
+				Kind:       "Secret",
+				APIVersion: "v1",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "production-01",
+				Namespace: "namespace",
+				Labels: map[string]string{
+					"argocd.argoproj.io/secret-type": "cluster",
+					"environment":                    "production",
+					"org":                            "bar",
+				},
+				Annotations: map[string]string{
+					"foo.argoproj.io": "production",
+				},
+			},
+			Data: map[string][]byte{
+				"config": []byte("{}"),
+				"name":   []byte("production-01"),
+				"server": []byte("https://production-01.example.com"),
+			},
+			Type: corev1.SecretType("Opaque"),
+		},
+	}
+
+	duckType := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": resourceApiVersion,
+			"kind":       "Duck",
+			"metadata": map[string]interface{}{
+				"name":      resourceName,
+				"namespace": "namespace",
+			},
+			"status": map[string]interface{}{
+				"decisions": []interface{}{
+					map[string]interface{}{
+						"clusterName": "staging-01",
+					},
+					map[string]interface{}{
+						"clusterName": "production-01",
+					},
+				},
+			},
+		},
+	}
+
+	duckTypeProdOnly := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": resourceApiVersion,
+			"kind":       "Duck",
+			"metadata": map[string]interface{}{
+				"name":      resourceName,
+				"namespace": "namespace",
+			},
+			"status": map[string]interface{}{
+				"decisions": []interface{}{
+					map[string]interface{}{
+						"clusterName": "production-01",
+					},
+				},
+			},
+		},
+	}
+
+	duckTypeEmpty := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": resourceApiVersion,
+			"kind":       "Duck",
+			"metadata": map[string]interface{}{
+				"name":      resourceName,
+				"namespace": "namespace",
+			},
+			"status": map[string]interface{}{},
+		},
+	}
+
+	configMap := &corev1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      "my-configmap",
+			Namespace: "namespace",
+		},
+		Data: map[string]string{
+			"apiVersion":    resourceApiVersion,
+			"kind":          resourceKind,
+			"statusListKey": "decisions",
+			"matchKey":      "clusterName",
+		},
+	}
+
+	testCases := []struct {
+		name         string
+		configMapRef string
+		resourceName string
+		resource     *unstructured.Unstructured
+		values       map[string]string
+		expected     []map[string]string
+		// clientError is true if a k8s client error should be simulated
+		clientError   bool
+		expectedError error
+	}{
+		{
+			name:          "no duck resource",
+			resourceName:  "",
+			resource:      duckType,
+			values:        nil,
+			expected:      []map[string]string{},
+			clientError:   false,
+			expectedError: errors.New("Invalid resource reference"),
+		},
+		{
+			name:          "invalid params for duck resource",
+			resourceName:  resourceName,
+			resource:      duckType,
+			values:        nil,
+			expected:      []map[string]string{},
+			clientError:   false,
+			expectedError: errors.New("duck.mallard.io \"quak\" not found"),
+		},
+		{
+			name:         "duck type generator",
+			resourceName: resourceName,
+			resource:     duckType,
+			values:       nil,
+			expected: []map[string]string{
+				{"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"},
+
+				{"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"},
+			},
+			clientError:   false,
+			expectedError: nil,
+		},
+		{
+			name:         "production-only",
+			resourceName: resourceName,
+			resource:     duckTypeProdOnly,
+			values: map[string]string{
+				"foo": "bar",
+			},
+			expected: []map[string]string{
+				{"clusterName": "production-01", "values.foo": "bar", "name": "production-01", "server": "https://production-01.example.com"},
+			},
+			clientError:   false,
+			expectedError: nil,
+		},
+		{
+			name:          "duck type empty status",
+			resourceName:  resourceName,
+			resource:      duckTypeEmpty,
+			values:        nil,
+			expected:      nil,
+			clientError:   false,
+			expectedError: errors.New("duck type status.decisions missing"),
+		},
+		{
+			name:          "simulate client error",
+			resourceName:  resourceName,
+			resource:      duckType,
+			values:        nil,
+			expected:      nil,
+			clientError:   true,
+			expectedError: errors.New("could not list Secrets"),
+		},
+	}
+
+	// convert []client.Object to []runtime.Object, for use by kubefake package
+	runtimeClusters := []runtime.Object{}
+	for _, clientCluster := range clusters {
+		runtimeClusters = append(runtimeClusters, clientCluster)
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			appClientset := kubefake.NewSimpleClientset(append(runtimeClusters, configMap)...)
+
+			fakeDynClient := dynfake.NewSimpleDynamicClient(runtime.NewScheme(), testCase.resource)
+
+			var duckTypeGenerator = NewDuckTypeGenerator(context.Background(), fakeDynClient, appClientset, "namespace")
+
+			got, err := duckTypeGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{
+				ClusterDecisionResource: &argoprojiov1alpha1.DuckTypeGenerator{
+					ConfigMapRef: "my-configmap",
+					Name:         testCase.resourceName,
+					Values:       testCase.values,
+				},
+			}, nil)
+
+			if testCase.expectedError != nil {
+				assert.Error(t, testCase.expectedError, err)
+			} else {
+				assert.NoError(t, err)
+				assert.ElementsMatch(t, testCase.expected, got)
+			}
+
+		})
+	}
+}
diff --git a/pkg/services/repo_service_test.go b/pkg/services/repo_service_test.go
index f3efac0..fa198e1 100644
--- a/pkg/services/repo_service_test.go
+++ b/pkg/services/repo_service_test.go
@@ -3,6 +3,8 @@ package services
 import (
 	"context"
 	"errors"
+	"os"
+	"path/filepath"
 	"sort"
 	"strings"
 	"testing"
@@ -319,7 +321,7 @@ func TestGetFileContent(t *testing.T) {
 			repoURL:       "https://github.com/argoproj/argocd-example-apps/",
 			revision:      commitID,
 			path:          "/this-file-does-not-exist.md",
-			expectedError: errors.New("open /tmp/https:__github.com_argoproj_argocd-example-apps_/this-file-does-not-exist.md: no such file or directory"),
+			expectedError: errors.New("open " + filepath.Join(os.TempDir()+"/https:__github.com_argoproj_argocd-example-apps_/this-file-does-not-exist.md"+": no such file or directory")),
 		},
 	}
 
diff --git a/test/e2e/applicationset/crl_e2e_test.go b/test/e2e/applicationset/crl_e2e_test.go
new file mode 100644
index 0000000..09509d5
--- /dev/null
+++ b/test/e2e/applicationset/crl_e2e_test.go
@@ -0,0 +1,407 @@
+package applicationsets
+
+import (
+	"testing"
+
+	"github.com/argoproj-labs/applicationset/api/v1alpha1"
+	. "github.com/argoproj-labs/applicationset/test/e2e/fixture/applicationsets"
+	"github.com/argoproj-labs/applicationset/test/e2e/fixture/applicationsets/utils"
+	argov1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+var tenSec = int64(10)
+
+func TestSimpleClusterResourceListGenerator(t *testing.T) {
+
+	expectedApp := argov1alpha1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Application",
+			APIVersion: "argoproj.io/v1alpha1",
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:       "cluster1-guestbook",
+			Namespace:  utils.ArgoCDNamespace,
+			Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
+		},
+		Spec: argov1alpha1.ApplicationSpec{
+			Project: "default",
+			Source: argov1alpha1.ApplicationSource{
+				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+				TargetRevision: "HEAD",
+				Path:           "guestbook",
+			},
+			Destination: argov1alpha1.ApplicationDestination{
+				Name:      "cluster1",
+				Namespace: "guestbook",
+			},
+		},
+	}
+
+	var expectedAppNewNamespace *argov1alpha1.Application
+	var expectedAppNewMetadata *argov1alpha1.Application
+
+	clusterList := []interface{}{
+		map[string]interface{}{
+			"clusterName": "cluster1",
+			"reason":      "argotest",
+		},
+	}
+
+	Given(t).
+		// Create a ClusterGenerator-based ApplicationSet
+		When().
+		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
+		CreatePlacementDecisionConfigMap("my-configmap").
+		CreatePlacementDecision("my-placementdecision").
+		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
+		Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{
+			Name: "simple-cluster-generator",
+		},
+			Spec: v1alpha1.ApplicationSetSpec{
+				Template: v1alpha1.ApplicationSetTemplate{
+					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
+					Spec: argov1alpha1.ApplicationSpec{
+						Project: "default",
+						Source: argov1alpha1.ApplicationSource{
+							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+							TargetRevision: "HEAD",
+							Path:           "guestbook",
+						},
+						Destination: argov1alpha1.ApplicationDestination{
+							Name: "{{clusterName}}",
+							// Server:    "{{server}}",
+							Namespace: "guestbook",
+						},
+					},
+				},
+				Generators: []v1alpha1.ApplicationSetGenerator{
+					{
+						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
+							ConfigMapRef: "my-configmap",
+							Name:         "my-placementdecision",
+						},
+					},
+				},
+			},
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})).
+
+		// Update the ApplicationSet template namespace, and verify it updates the Applications
+		When().
+		And(func() {
+			expectedAppNewNamespace = expectedApp.DeepCopy()
+			expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2"
+		}).
+		Update(func(appset *v1alpha1.ApplicationSet) {
+			appset.Spec.Template.Spec.Destination.Namespace = "guestbook2"
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})).
+
+		// Update the metadata fields in the appset template, and make sure it propagates to the apps
+		When().
+		And(func() {
+			expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
+			expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
+			expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
+		}).
+		Update(func(appset *v1alpha1.ApplicationSet) {
+			appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
+			appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"}
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})).
+
+		// Delete the ApplicationSet, and verify it deletes the Applications
+		When().
+		Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace}))
+}
+
+func TestSimpleClusterResourceListGeneratorAddingCluster(t *testing.T) {
+
+	expectedAppTemplate := argov1alpha1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Application",
+			APIVersion: "argoproj.io/v1alpha1",
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:       "{{name}}-guestbook",
+			Namespace:  utils.ArgoCDNamespace,
+			Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
+		},
+		Spec: argov1alpha1.ApplicationSpec{
+			Project: "default",
+			Source: argov1alpha1.ApplicationSource{
+				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+				TargetRevision: "HEAD",
+				Path:           "guestbook",
+			},
+			Destination: argov1alpha1.ApplicationDestination{
+				Name:      "{{clusterName}}",
+				Namespace: "guestbook",
+			},
+		},
+	}
+
+	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster1.Spec.Destination.Name = "cluster1"
+	expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook"
+
+	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster2.Spec.Destination.Name = "cluster2"
+	expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook"
+
+	clusterList := []interface{}{
+		map[string]interface{}{
+			"clusterName": "cluster1",
+			"reason":      "argotest",
+		},
+		map[string]interface{}{
+			"clusterName": "cluster2",
+			"reason":      "argotest",
+		},
+	}
+
+	Given(t).
+		// Create a ClusterGenerator-based ApplicationSet
+		When().
+		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
+		CreatePlacementDecisionConfigMap("my-configmap").
+		CreatePlacementDecision("my-placementdecision").
+		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
+		Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{
+			Name: "simple-cluster-generator",
+		},
+			Spec: v1alpha1.ApplicationSetSpec{
+				Template: v1alpha1.ApplicationSetTemplate{
+					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
+					Spec: argov1alpha1.ApplicationSpec{
+						Project: "default",
+						Source: argov1alpha1.ApplicationSource{
+							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+							TargetRevision: "HEAD",
+							Path:           "guestbook",
+						},
+						Destination: argov1alpha1.ApplicationDestination{
+							Name: "{{clusterName}}",
+							// Server:    "{{server}}",
+							Namespace: "guestbook",
+						},
+					},
+				},
+				Generators: []v1alpha1.ApplicationSetGenerator{
+					{
+						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
+							ConfigMapRef:        "my-configmap",
+							Name:                "my-placementdecision",
+							RequeueAfterSeconds: &tenSec,
+						},
+					},
+				},
+			},
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})).
+
+		// Update the ApplicationSet template namespace, and verify it updates the Applications
+		When().
+		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
+		Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
+
+		// Delete the ApplicationSet, and verify it deletes the Applications
+		When().
+		Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2}))
+}
+
+func TestSimpleClusterResourceListGeneratorDeletingClusterSecret(t *testing.T) {
+
+	expectedAppTemplate := argov1alpha1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Application",
+			APIVersion: "argoproj.io/v1alpha1",
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:       "{{name}}-guestbook",
+			Namespace:  utils.ArgoCDNamespace,
+			Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
+		},
+		Spec: argov1alpha1.ApplicationSpec{
+			Project: "default",
+			Source: argov1alpha1.ApplicationSource{
+				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+				TargetRevision: "HEAD",
+				Path:           "guestbook",
+			},
+			Destination: argov1alpha1.ApplicationDestination{
+				Name:      "{{name}}",
+				Namespace: "guestbook",
+			},
+		},
+	}
+
+	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster1.Spec.Destination.Name = "cluster1"
+	expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook"
+
+	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster2.Spec.Destination.Name = "cluster2"
+	expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook"
+
+	clusterList := []interface{}{
+		map[string]interface{}{
+			"clusterName": "cluster1",
+			"reason":      "argotest",
+		},
+		map[string]interface{}{
+			"clusterName": "cluster2",
+			"reason":      "argotest",
+		},
+	}
+
+	Given(t).
+		// Create a ClusterGenerator-based ApplicationSet
+		When().
+		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
+		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
+		CreatePlacementDecisionConfigMap("my-configmap").
+		CreatePlacementDecision("my-placementdecision").
+		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
+		Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{
+			Name: "simple-cluster-generator",
+		},
+			Spec: v1alpha1.ApplicationSetSpec{
+				Template: v1alpha1.ApplicationSetTemplate{
+					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
+					Spec: argov1alpha1.ApplicationSpec{
+						Project: "default",
+						Source: argov1alpha1.ApplicationSource{
+							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+							TargetRevision: "HEAD",
+							Path:           "guestbook",
+						},
+						Destination: argov1alpha1.ApplicationDestination{
+							Name: "{{clusterName}}",
+							// Server:    "{{server}}",
+							Namespace: "guestbook",
+						},
+					},
+				},
+				Generators: []v1alpha1.ApplicationSetGenerator{
+					{
+						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
+							ConfigMapRef:        "my-configmap",
+							Name:                "my-placementdecision",
+							RequeueAfterSeconds: &tenSec,
+						},
+					},
+				},
+			},
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
+
+		// Update the ApplicationSet template namespace, and verify it updates the Applications
+		When().
+		DeleteClusterSecret("my-secret2").
+		Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})).
+		Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})).
+
+		// Delete the ApplicationSet, and verify it deletes the Applications
+		When().
+		Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1}))
+}
+
+func TestSimpleClusterResourceListGeneratorDeletingClusterFromResource(t *testing.T) {
+
+	expectedAppTemplate := argov1alpha1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Application",
+			APIVersion: "argoproj.io/v1alpha1",
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:       "{{name}}-guestbook",
+			Namespace:  utils.ArgoCDNamespace,
+			Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
+		},
+		Spec: argov1alpha1.ApplicationSpec{
+			Project: "default",
+			Source: argov1alpha1.ApplicationSource{
+				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+				TargetRevision: "HEAD",
+				Path:           "guestbook",
+			},
+			Destination: argov1alpha1.ApplicationDestination{
+				Name:      "{{name}}",
+				Namespace: "guestbook",
+			},
+		},
+	}
+
+	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster1.Spec.Destination.Name = "cluster1"
+	expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook"
+
+	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
+	expectedAppCluster2.Spec.Destination.Name = "cluster2"
+	expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook"
+
+	clusterList := []interface{}{
+		map[string]interface{}{
+			"clusterName": "cluster1",
+			"reason":      "argotest",
+		},
+		map[string]interface{}{
+			"clusterName": "cluster2",
+			"reason":      "argotest",
+		},
+	}
+
+	clusterListSmall := []interface{}{
+		map[string]interface{}{
+			"clusterName": "cluster1",
+			"reason":      "argotest",
+		},
+	}
+
+	Given(t).
+		// Create a ClusterGenerator-based ApplicationSet
+		When().
+		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
+		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
+		CreatePlacementDecisionConfigMap("my-configmap").
+		CreatePlacementDecision("my-placementdecision").
+		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
+		Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{
+			Name: "simple-cluster-generator",
+		},
+			Spec: v1alpha1.ApplicationSetSpec{
+				Template: v1alpha1.ApplicationSetTemplate{
+					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
+					Spec: argov1alpha1.ApplicationSpec{
+						Project: "default",
+						Source: argov1alpha1.ApplicationSource{
+							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
+							TargetRevision: "HEAD",
+							Path:           "guestbook",
+						},
+						Destination: argov1alpha1.ApplicationDestination{
+							Name: "{{clusterName}}",
+							// Server:    "{{server}}",
+							Namespace: "guestbook",
+						},
+					},
+				},
+				Generators: []v1alpha1.ApplicationSetGenerator{
+					{
+						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
+							ConfigMapRef:        "my-configmap",
+							Name:                "my-placementdecision",
+							RequeueAfterSeconds: &tenSec,
+						},
+					},
+				},
+			},
+		}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
+
+		// Update the ApplicationSet template namespace, and verify it updates the Applications
+		When().
+		StatusUpdatePlacementDecision("my-placementdecision", clusterListSmall).
+		Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})).
+		Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})).
+
+		// Delete the ApplicationSet, and verify it deletes the Applications
+		When().
+		Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1}))
+}
diff --git a/test/e2e/fixture/applicationsets/actions.go b/test/e2e/fixture/applicationsets/actions.go
index a1ad4a0..ea027e4 100644
--- a/test/e2e/fixture/applicationsets/actions.go
+++ b/test/e2e/fixture/applicationsets/actions.go
@@ -11,6 +11,8 @@ import (
 	log "github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 )
 
 // this implements the "when" part of given/when/then
@@ -25,6 +27,12 @@ type Actions struct {
 	ignoreErrors   bool
 }
 
+var pdGVR = schema.GroupVersionResource{
+	Group:    "cluster.open-cluster-management.io",
+	Version:  "v1alpha1",
+	Resource: "placementdecisions",
+}
+
 // IgnoreErrors sets whether to ignore
 func (a *Actions) IgnoreErrors() *Actions {
 	a.ignoreErrors = true
@@ -89,6 +97,30 @@ func (a *Actions) DeleteClusterSecret(secretName string) *Actions {
 	return a
 }
 
+// DeleteConfigMap deletes a faux cluster secret
+func (a *Actions) DeleteConfigMap(configMapName string) *Actions {
+
+	err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().ConfigMaps(utils.ArgoCDNamespace).Delete(context.Background(), configMapName, metav1.DeleteOptions{})
+
+	a.describeAction = fmt.Sprintf("deleting configMap '%s'", configMapName)
+	a.lastOutput, a.lastError = "", err
+	a.verifyAction()
+
+	return a
+}
+
+// DeletePlacementDecision deletes a faux cluster secret
+func (a *Actions) DeletePlacementDecision(placementDecisionName string) *Actions {
+
+	err := utils.GetE2EFixtureK8sClient().DynamicClientset.Resource(pdGVR).Namespace(utils.ArgoCDNamespace).Delete(context.Background(), placementDecisionName, metav1.DeleteOptions{})
+
+	a.describeAction = fmt.Sprintf("deleting placement decision '%s'", placementDecisionName)
+	a.lastOutput, a.lastError = "", err
+	a.verifyAction()
+
+	return a
+}
+
 // Create a temporary namespace, from utils.ApplicationSet, for use by the test.
 // This namespace will be deleted on subsequent tests.
 func (a *Actions) CreateNamespace() *Actions {
@@ -127,6 +159,103 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions {
 	return a
 }
 
+// Create a ConfigMap for the ClusterResourceList generator
+func (a *Actions) CreatePlacementDecisionConfigMap(configMapName string) *Actions {
+	a.context.t.Helper()
+
+	fixtureClient := utils.GetE2EFixtureK8sClient()
+
+	_, err := fixtureClient.KubeClientset.CoreV1().ConfigMaps(utils.ArgoCDNamespace).Get(context.Background(), configMapName, metav1.GetOptions{})
+
+	// Don't do anything if it exists
+	if err == nil {
+		return a
+	}
+
+	_, err = fixtureClient.KubeClientset.CoreV1().ConfigMaps(utils.ArgoCDNamespace).Create(context.Background(),
+		&corev1.ConfigMap{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: configMapName,
+			},
+			Data: map[string]string{
+				"apiVersion":    "cluster.open-cluster-management.io/v1alpha1",
+				"kind":          "placementdecisions",
+				"statusListKey": "decisions",
+				"matchKey":      "clusterName",
+			},
+		}, metav1.CreateOptions{})
+
+	a.describeAction = fmt.Sprintf("creating configmap '%s'", configMapName)
+	a.lastOutput, a.lastError = "", err
+	a.verifyAction()
+
+	return a
+}
+
+func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions {
+	a.context.t.Helper()
+
+	fixtureClient := utils.GetE2EFixtureK8sClient().DynamicClientset
+
+	_, err := fixtureClient.Resource(pdGVR).Namespace(utils.ArgoCDNamespace).Get(
+		context.Background(),
+		placementDecisionName,
+		metav1.GetOptions{})
+	// If already exists
+	if err == nil {
+		return a
+	}
+
+	placementDecision := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"metadata": map[string]interface{}{
+				"name":      placementDecisionName,
+				"namespace": utils.ArgoCDNamespace,
+			},
+			"kind":       "PlacementDecision",
+			"apiVersion": "cluster.open-cluster-management.io/v1alpha1",
+			"status":     map[string]interface{}{},
+		},
+	}
+
+	_, err = fixtureClient.Resource(pdGVR).Namespace(utils.ArgoCDNamespace).Create(
+		context.Background(),
+		placementDecision,
+		metav1.CreateOptions{})
+
+	a.describeAction = fmt.Sprintf("creating placementDecision '%v'", placementDecisionName)
+	a.lastOutput, a.lastError = "", err
+	a.verifyAction()
+
+	return a
+}
+
+func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, clusterList []interface{}) *Actions {
+	a.context.t.Helper()
+
+	fixtureClient := utils.GetE2EFixtureK8sClient().DynamicClientset
+	placementDecision, err := fixtureClient.Resource(pdGVR).Namespace(utils.ArgoCDNamespace).Get(
+		context.Background(),
+		placementDecisionName,
+		metav1.GetOptions{})
+
+	placementDecision.Object["status"] = map[string]interface{}{
+		"decisions": clusterList,
+	}
+
+	if err == nil {
+		_, err = fixtureClient.Resource(pdGVR).Namespace(utils.ArgoCDNamespace).UpdateStatus(
+			context.Background(),
+			placementDecision,
+			metav1.UpdateOptions{})
+	}
+	a.describeAction = fmt.Sprintf("status update placementDecision for '%v'", clusterList)
+	a.lastOutput, a.lastError = "", err
+	a.verifyAction()
+
+	return a
+}
+
 // Delete deletes the ApplicationSet within the context
 func (a *Actions) Delete() *Actions {
 	a.context.t.Helper()