Repository: argoproj-labs/applicationset
Pull request #9 (2020-07-07 20:32:28)

Create applications

xianlubird: @OmerKahani Pls help fix the conflict

Patch:
diff --git a/go.mod b/go.mod
index e337e6a..38d7d0b 100644
--- a/go.mod
+++ b/go.mod
@@ -15,6 +15,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sirupsen/logrus v1.4.2
+	github.com/stretchr/testify v1.4.0
 	github.com/valyala/fasttemplate v1.1.1
 	github.com/yudai/gojsondiff v1.0.1-0.20180504020246-0525c875b75c // indirect
 	github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
@@ -26,7 +27,7 @@ require (
 	k8s.io/client-go v11.0.1-0.20190816222228-6d55c1b1f1ca+incompatible
 	k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a // indirect
 	k8s.io/kubectl v0.16.6 // indirect
-	k8s.io/kubernetes v1.16.6 // indirect
+	k8s.io/kubernetes v1.16.6
 	k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6 // indirect
 	sigs.k8s.io/controller-runtime v0.5.0
 )
diff --git a/main.go b/main.go
index ccc92a1..615d745 100644
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"flag"
+	argov1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"os"
 
 	"k8s.io/apimachinery/pkg/runtime"
@@ -24,6 +25,8 @@ func init() {
 	_ = clientgoscheme.AddToScheme(scheme)
 
 	_ = argoprojiov1alpha1.AddToScheme(scheme)
+
+	_ = argov1alpha1.AddToScheme(scheme)
 	// +kubebuilder:scaffold:scheme
 }
 
diff --git a/pkg/controllers/applicationset_controller.go b/pkg/controllers/applicationset_controller.go
index b546f0b..53acd53 100644
--- a/pkg/controllers/applicationset_controller.go
+++ b/pkg/controllers/applicationset_controller.go
@@ -18,9 +18,11 @@ package controllers
 
 import (
 	"context"
+	"fmt"
 	"github.com/argoproj-labs/applicationset/pkg/generators"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/client-go/tools/record"
+	"k8s.io/kubernetes/pkg/apis/core"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/source"
 
@@ -50,7 +52,7 @@ func (r *ApplicationSetReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err
 
 	var applicationSetInfo argoprojiov1alpha1.ApplicationSet
 	if err := r.Get(ctx, req.NamespacedName, &applicationSetInfo); err != nil {
-		log.Info("Unable to fetch applicationSetInfo %v", err)
+		log.Infof("Unable to fetch applicationSetInfo %e", err)
 		return ctrl.Result{}, client.IgnoreNotFound(err)
 	}
 
@@ -58,7 +60,7 @@ func (r *ApplicationSetReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err
 	clusterGenerator := generators.NewClusterGenerator(r.Client)
 
 	// desiredApplications is the main list of all expected Applications from all generators in this appset.
-	var desiredApplications  []argov1alpha1.Application
+	var desiredApplications []argov1alpha1.Application
 	for _, tmpGenerator := range applicationSetInfo.Spec.Generators {
 		var apps []argov1alpha1.Application
 		var err error
@@ -72,6 +74,12 @@ func (r *ApplicationSetReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err
 			log.WithError(err).Error("error generating applications")
 		}
 		desiredApplications = append(desiredApplications, apps...)
+
+	}
+
+	if err := r.createApplications(ctx, applicationSetInfo, desiredApplications); err != nil {
+		log.Infof("Unable to create applications applicationSetInfo %e", err)
+		return ctrl.Result{}, err
 	}
 
 	return ctrl.Result{}, nil
@@ -84,11 +92,27 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager) error {
 			&source.Kind{Type: &corev1.Secret{}},
 			&clusterSecretEventHandler{
 				Client: mgr.GetClient(),
-				Log: log.WithField("type", "createSecretEventHandler"),
+				Log:    log.WithField("type", "createSecretEventHandler"),
 			}).
 		// TODO: also watch Applications and respond on changes if we own them.
 		Complete(r)
 }
 
-var _ handler.EventHandler = &clusterSecretEventHandler{}
+func (r *ApplicationSetReconciler) createApplications(ctx context.Context, applicationSetInfo argoprojiov1alpha1.ApplicationSet, appList []argov1alpha1.Application) error {
+
+	for _, app := range appList {
+		app.Namespace = applicationSetInfo.Namespace
+		if err := r.Client.Create(ctx, &app); err != nil {
+			log.Error(err, fmt.Sprintf("failed to create Application %s resource for applicationSet %s", app.Name, applicationSetInfo.Name))
+			continue
+		}
 
+		r.Recorder.Eventf(&applicationSetInfo, core.EventTypeNormal, "Created", "Created Application %q", app.Name)
+		log.Infof("created Application %s resource for applicationSet %s", app.Name, applicationSetInfo.Name)
+	}
+
+	return nil
+
+}
+
+var _ handler.EventHandler = &clusterSecretEventHandler{}


Test patch:
diff --git a/pkg/controllers/applicationset_controller_test.go b/pkg/controllers/applicationset_controller_test.go
new file mode 100644
index 0000000..33fd0ea
--- /dev/null
+++ b/pkg/controllers/applicationset_controller_test.go
@@ -0,0 +1,78 @@
+package controllers
+
+import (
+	"context"
+	argov1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
+	"github.com/stretchr/testify/assert"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/tools/record"
+	crtclient "sigs.k8s.io/controller-runtime/pkg/client"
+	"testing"
+
+	argoprojiov1alpha1 "github.com/argoproj-labs/applicationset/api/v1alpha1"
+
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+)
+
+func TestCreateApplications(t *testing.T) {
+
+	scheme := runtime.NewScheme()
+	argov1alpha1.AddToScheme(scheme)
+
+	client := fake.NewFakeClientWithScheme(scheme)
+
+	r := ApplicationSetReconciler{
+		Client:   client,
+		Scheme:   scheme,
+		Recorder: record.NewFakeRecorder(1),
+	}
+
+	for _, c := range []struct {
+		appSet   argoprojiov1alpha1.ApplicationSet
+		apps     []argov1alpha1.Application
+		expected []argov1alpha1.Application
+	}{
+		{
+			appSet: argoprojiov1alpha1.ApplicationSet{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "name",
+					Namespace: "namespace",
+				},
+			},
+			apps: []argov1alpha1.Application{
+				{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "app1",
+					},
+				},
+			},
+			expected: []argov1alpha1.Application{
+				{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "Application",
+						APIVersion: "argoproj.io/v1alpha1",
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name:            "app1",
+						Namespace:       "namespace",
+						ResourceVersion: "1",
+					},
+				},
+			},
+		},
+	} {
+		r.createApplications(context.TODO(), c.appSet, c.apps)
+
+		for _, e := range c.expected {
+			got := &argov1alpha1.Application{}
+			_ = client.Get(context.Background(), crtclient.ObjectKey{
+				Namespace: e.Namespace,
+				Name:      e.Name,
+			}, got)
+
+			assert.Equal(t, e, *got)
+		}
+	}
+
+}