-
Notifications
You must be signed in to change notification settings - Fork 277
Update #11
Update #11
Changes from 5 commits
84b34c2
991c628
8330ca4
64a7159
a98f1a9
72610f1
21b2a62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ import ( | |
"fmt" | ||
"github.com/argoproj-labs/applicationset/pkg/generators" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/tools/record" | ||
"k8s.io/kubernetes/pkg/apis/core" | ||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | ||
|
@@ -78,17 +79,34 @@ func (r *ApplicationSetReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err | |
|
||
} | ||
|
||
if err := r.createApplications(ctx, applicationSetInfo, desiredApplications); err != nil { | ||
log.Infof("Unable to create applications applicationSetInfo %e", err) | ||
return ctrl.Result{}, err | ||
} | ||
r.createOrUpdateInCluster(ctx, applicationSetInfo, desiredApplications) | ||
r.deleteInCluster(ctx, applicationSetInfo, desiredApplications) | ||
|
||
return ctrl.Result{}, nil | ||
} | ||
|
||
func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager) error { | ||
if err := mgr.GetFieldIndexer().IndexField(&argov1alpha1.Application{}, ".metadata.controller", func(rawObj runtime.Object) []string { | ||
// grab the job object, extract the owner... | ||
app := rawObj.(*argov1alpha1.Application) | ||
owner := metav1.GetControllerOf(app) | ||
if owner == nil { | ||
return nil | ||
} | ||
// ...make sure it's a application set... | ||
if owner.APIVersion != argoprojiov1alpha1.GroupVersion.String() || owner.Kind != "ApplicationSet" { | ||
return nil | ||
} | ||
|
||
// ...and if so, return it | ||
return []string{owner.Name} | ||
}); err != nil { | ||
return err | ||
} | ||
|
||
return ctrl.NewControllerManagedBy(mgr). | ||
For(&argoprojiov1alpha1.ApplicationSet{}). | ||
Owns(&argov1alpha1.Application{}). | ||
Watches( | ||
&source.Kind{Type: &corev1.Secret{}}, | ||
&clusterSecretEventHandler{ | ||
|
@@ -99,34 +117,60 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager) error { | |
Complete(r) | ||
} | ||
|
||
func (r *ApplicationSetReconciler) createApplications(ctx context.Context, applicationSetInfo argoprojiov1alpha1.ApplicationSet, appList []argov1alpha1.Application) error { | ||
// createOrUpdateInCluster will create / update application resources in the cluster. | ||
// For new application it will call create | ||
// For application that need to update it will call update | ||
// The function also adds owner reference to all applications, and uses it for delete them. | ||
func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, applicationSet argoprojiov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) { | ||
|
||
for _, app := range appList { | ||
app.Namespace = applicationSetInfo.Namespace | ||
//create or updates the application in appList | ||
for _, app := range desiredApplications { | ||
app.Namespace = applicationSet.Namespace | ||
|
||
found := app | ||
action, err := ctrl.CreateOrUpdate(ctx, r.Client, &found, func() error { | ||
found.Spec = app.Spec | ||
return controllerutil.SetControllerReference(&applicationSetInfo, &found, r.Scheme) | ||
return controllerutil.SetControllerReference(&applicationSet, &found, r.Scheme) | ||
}) | ||
|
||
if err != nil { | ||
log.Error(err, fmt.Sprintf("failed to get Application %s resource for applicationSet %s", app.Name, applicationSetInfo.Name)) | ||
log.Error(err, fmt.Sprintf("failed to CreateOrUpdate Application %s resource for applicationSet %s", app.Name, applicationSet.Name)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a suggestion for using logrus and structured logging: Define a logger with context within your loop: appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": applicationSet.Name}) Then use appLog within the loop. appLog.WithError(err).Error("failed to CreateOrUpdate Application") There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added thanks! |
||
continue | ||
} | ||
|
||
r.Recorder.Eventf(&applicationSetInfo, core.EventTypeNormal, "Created", "Created Application %q", app.Name) | ||
log.Infof("%s Application %s resource for applicationSet %s", action, app.Name, applicationSetInfo.Name) | ||
r.Recorder.Eventf(&applicationSet, core.EventTypeNormal, fmt.Sprint(action), "%s Application %q", action, app.Name) | ||
log.Infof("%s Application %s resource for applicationSet %s", action, app.Name, applicationSet.Name) | ||
} | ||
} | ||
|
||
return nil | ||
// deleteInCluster will delete application that are current in the cluster but not in appList. | ||
// The function must be called after all generators had been called and generated applications | ||
func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, applicationSet argoprojiov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) { | ||
|
||
} | ||
// Save current applications to be able to delete the ones that are not in appList | ||
var current argov1alpha1.ApplicationList | ||
_ = r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}) | ||
|
||
func (r *ApplicationSetReconciler) getApplications(ctx context.Context, applicationSetInfo argoprojiov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { | ||
m := make(map[string]bool) // Will holds the app names in appList for the deletion process | ||
|
||
return nil, nil | ||
for _, app := range desiredApplications { | ||
m[app.Name] = true | ||
} | ||
|
||
// Delete apps that are not in m[string]bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should separate out this function , delete application shouldn't exists in apply function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
for _, app := range current.Items { | ||
_, exists := m[app.Name] | ||
|
||
if exists == false { | ||
err := r.Client.Delete(ctx, &app) | ||
if err != nil { | ||
log.Error(err, fmt.Sprintf("failed to delete Application %s resource for applicationSet %s", app.Name, applicationSet.Name)) | ||
continue | ||
} | ||
r.Recorder.Eventf(&applicationSet, core.EventTypeNormal, "Deleted", "Deleted Application %q", app.Name) | ||
log.Infof("Deleted Application %s resource for applicationSet %s", app.Name, applicationSet.Name) | ||
} | ||
} | ||
} | ||
|
||
var _ handler.EventHandler = &clusterSecretEventHandler{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have some
if conditions
, like iffinalizers
is set , we should delete this cluster?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is what you meant, we definitely will want to add a finalizer to ApplicationSets, and if deleting the appset we must cleanup all Applications before removing that finalizer. Deletion cleanup should probably be a separate PR. I can try to find some time for this one this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function deletes old applications from the cluster (deleted record from a list)
Deletion of ApplicationSets is implemented with owner reference so the Kubernetes GC will catch it and delete the applications
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
going over the proposal, every application should have
resources-finalizer.argocd.argoproj.io
entry inmetadata.finalizers
- Added it, thanks!Do we also want to support the option to delete a record from a list / directory from git, and not run the finalizers in the application (something like
kubectl delete app NAME --cascade=false
) ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need to implement this for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, forgot about that!