Repository: argoproj-labs/applicationset (go)

Issue:
Move presently unimplemented examples out of examples/ root directory, update proposal links
The `examples/` directory of this repo contains a number of examples that are currently not implemented in the code (and are thus examples of how a developer *should implement in a future release*, not how to use for current users). This may be confusing for new users (and was confusing to me when initially onboarding to ApplicationSet controller), so we should move them to a subdir of examples/ and properly label them.

We can:
- Create a new `examples/proposed` directory (other suggestions for name/location are welcome!) that contains examples which are not yet implemented, leaving the root `examples/` directory for working examples. 
- Create a markdown file in the proposed directory saying the examples are not implemented in the code yet.
- The proposal doc contains direct links to these examples, and  we would should update the proposal doc to the new location. **Note**: We don't have edit access to the doc, only suggestion access, but my guess is one of the Argo CD principals should have edit access (perhaps Jesse?) and would be able to approve the changes.

Examples can "graduate" out of `proposed` as they are implemented.


Pull request:
making examples more clear
Closes #77.

- Move filter to proposal.
- Delete the generic applicationset example; the use-case examples are more detailed
- Added values to the cluster example

Patch:
diff --git a/api/v1alpha1/applicationset_types.go b/api/v1alpha1/applicationset_types.go
index 1c95f52..570189d 100644
--- a/api/v1alpha1/applicationset_types.go
+++ b/api/v1alpha1/applicationset_types.go
@@ -68,6 +68,8 @@ type ListGenerator struct {
 type ListGeneratorElement struct {
 	Cluster string `json:"cluster"`
 	Url     string `json:"url"`
+	// Values contains key/value pairs which are passed directly as parameters to the template
+	Values map[string]string `json:"values,omitempty"`
 }
 
 // ClusterGenerator defines a generator to match against clusters registered with ArgoCD.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index a4e1d97..d51e4dd 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -274,7 +274,9 @@ func (in *ListGenerator) DeepCopyInto(out *ListGenerator) {
 	if in.Elements != nil {
 		in, out := &in.Elements, &out.Elements
 		*out = make([]ListGeneratorElement, len(*in))
-		copy(*out, *in)
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
 	}
 	in.Template.DeepCopyInto(&out.Template)
 }
@@ -292,6 +294,13 @@ func (in *ListGenerator) DeepCopy() *ListGenerator {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ListGeneratorElement) DeepCopyInto(out *ListGeneratorElement) {
 	*out = *in
+	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 ListGeneratorElement.
diff --git a/examples/applicationset.yaml b/examples/applicationset.yaml
deleted file mode 100644
index 8249b72..0000000
--- a/examples/applicationset.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-# This is an example of a typical ApplicationSet which uses the cluster generator.
-# An ApplicationSet is comprised with two stanzas:
-#  - spec.generator - producer of a list of values supplied as arguments to an app template
-#  - spec.template - an application template, which has been parameterized
-apiVersion: argoproj.io/v1alpha1
-kind: ApplicationSet
-metadata:
-  name: guestbook
-spec:
-  generators:
-  - clusters: {}
-  template:
-    metadata:
-      name: '{{name}}-guestbook'
-    spec:
-      source:
-        repoURL: https://github.com/infra-team/cluster-deployments.git
-        targetRevision: HEAD
-        chart: guestbook
-      destination:
-        server: '{{server}}'
-        namespace: guestbook
diff --git a/examples/clusters.yaml b/examples/clusters.yaml
index 3399829..966455a 100644
--- a/examples/clusters.yaml
+++ b/examples/clusters.yaml
@@ -4,6 +4,7 @@
 #  - server
 #  - metadata.labels.<key>
 #  - metadata.annotations.<key>
+#  - values.<key>
 apiVersion: argoproj.io/v1alpha1
 kind: ApplicationSet
 metadata:
@@ -14,13 +15,15 @@ spec:
       selector:
         matchLabels:
           argocd.argoproj.io/secret-type: cluster
+      values:
+        project: default
   template:
     metadata:
       name: '{{name}}-guestbook'
       labels:
         environment: '{{metadata.labels.environment}}'
     spec:
-      project: ""
+      project: '{{values.project}}'
       source:
         repoURL: https://github.com/infra-team/cluster-deployments.git
         targetRevision: HEAD
diff --git a/examples/list.yaml b/examples/list.yaml
index 97c6c17..7cdbc55 100644
--- a/examples/list.yaml
+++ b/examples/list.yaml
@@ -9,15 +9,21 @@ spec:
       elements:
       - cluster: engineering-dev
         url: https://1.2.3.4
+        values:
+          project: dev
       - cluster: engineering-prod
         url: https://2.4.6.8
+        values:
+          project: prod
       - cluster: finance-preprod
         url: https://9.8.7.6
+        values:
+          project: preprod
   template:
     metadata:
       name: '{{cluster}}-guestbook'
     spec:
-      project: ""
+      project: '{{values.project}}'
       source:
         repoURL: https://github.com/infra-team/cluster-deployments.git
         targetRevision: HEAD
diff --git a/examples/proposal/README.md b/examples/proposal/README.md
new file mode 100644
index 0000000..5839139
--- /dev/null
+++ b/examples/proposal/README.md
@@ -0,0 +1,3 @@
+# Proposal Examples
+This directory contains examples that are not yet implemented.
+They are part of the project to indicate future progress, and we are welcome any contribution that will add an implementation
diff --git a/examples/filters.yaml b/examples/proposal/filters.yaml
similarity index 100%
rename from examples/filters.yaml
rename to examples/proposal/filters.yaml
diff --git a/manifests/crds/argoproj.io_applicationsets.yaml b/manifests/crds/argoproj.io_applicationsets.yaml
index f4e2e06..9421913 100644
--- a/manifests/crds/argoproj.io_applicationsets.yaml
+++ b/manifests/crds/argoproj.io_applicationsets.yaml
@@ -886,6 +886,12 @@ spec:
                               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
diff --git a/manifests/install.yaml b/manifests/install.yaml
index d6f4941..c21923a 100644
--- a/manifests/install.yaml
+++ b/manifests/install.yaml
@@ -716,6 +716,11 @@ spec:
                               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
diff --git a/pkg/generators/list.go b/pkg/generators/list.go
index ee3fd32..8997bfa 100644
--- a/pkg/generators/list.go
+++ b/pkg/generators/list.go
@@ -1,6 +1,7 @@
 package generators
 
 import (
+	"fmt"
 	"time"
 
 	argoprojiov1alpha1 "github.com/argoproj-labs/applicationset/api/v1alpha1"
@@ -37,9 +38,12 @@ func (g *ListGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Appli
 	res := make([]map[string]string, len(appSetGenerator.List.Elements))
 
 	for i, tmpItem := range appSetGenerator.List.Elements {
-		params := make(map[string]string, 2)
+		params := make(map[string]string, 2+len(tmpItem.Values))
 		params[utils.ClusterListGeneratorKeyName] = tmpItem.Cluster
 		params[utils.UrlGeneratorKeyName] = tmpItem.Url
+		for key, value := range tmpItem.Values {
+			params[fmt.Sprintf("values.%s", key)] = value
+		}
 		res[i] = params
 	}
 


Test patch:
diff --git a/pkg/generators/list_test.go b/pkg/generators/list_test.go
new file mode 100644
index 0000000..74b36ac
--- /dev/null
+++ b/pkg/generators/list_test.go
@@ -0,0 +1,40 @@
+package generators
+
+import (
+	"testing"
+
+	argoprojiov1alpha1 "github.com/argoproj-labs/applicationset/api/v1alpha1"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGenerateListParams(t *testing.T) {
+	testCases := []struct {
+		elements []argoprojiov1alpha1.ListGeneratorElement
+		expected []map[string]string
+	}{
+		{
+			elements: []argoprojiov1alpha1.ListGeneratorElement{{Cluster: "cluster", Url: "url", Values: map[string]string{}}}, expected: []map[string]string{{
+				"cluster": "cluster", "url": "url"},
+			},
+		},
+		{
+			elements: []argoprojiov1alpha1.ListGeneratorElement{{Cluster: "cluster", Url: "url", Values: map[string]string{"foo": "bar"}}}, expected: []map[string]string{{
+				"cluster": "cluster", "url": "url", "values.foo": "bar",
+			}},
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		var listGenerator = NewListGenerator()
+
+		got, err := listGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{List: &argoprojiov1alpha1.ListGenerator{
+			Elements: testCase.elements,
+		}})
+
+		assert.NoError(t, err)
+		assert.ElementsMatch(t, testCase.expected, got)
+
+	}
+}