Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): add cmd to preview generated apps of appsets (#10895) #16781

Merged
merged 40 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ccf1bd3
feat(cli): add cmd to preview generated apps
agaudreault Nov 22, 2023
769ecbe
fix build
agaudreault Nov 22, 2023
ba26a06
fix local proto gen
agaudreault Dec 3, 2023
89d69a5
dry run client
agaudreault Dec 3, 2023
76e3c9e
fix: allow to run codegen outside GOPATH
agaudreault Dec 3, 2023
0b9d5a5
clientgen
agaudreault Dec 6, 2023
d05e112
openapigen
agaudreault Dec 6, 2023
9ca2fd7
remove ensure-gopath
agaudreault Dec 6, 2023
f68faa5
Merge branch 'master' into fix-local-codegen
agaudreault Dec 6, 2023
d4243b0
Merge remote-tracking branch 'origin/fix-local-codegen' into appset-l…
agaudreault Dec 6, 2023
04a9f6e
fix tests and templatePatch
agaudreault Jan 9, 2024
42ea8c9
Merge remote-tracking branch 'upstream/master' into appset-list-apps
agaudreault Jan 9, 2024
38fc7db
fix build
agaudreault Jan 9, 2024
3f51c0e
convert to interfaces
agaudreault Jan 9, 2024
317122c
Merge remote-tracking branch 'upstream/master' into appset-list-apps
agaudreault Jan 10, 2024
47f1bc4
Merge branch 'master' into appset-list-apps
agaudreault Jan 12, 2024
b6ba672
Merge remote-tracking branch 'upstream/master' into appset-list-apps
agaudreault Jan 22, 2024
2391dbd
Merge branch 'master' into appset-list-apps
agaudreault Feb 8, 2024
f2ae013
Merge remote-tracking branch 'origin/master' into appset-list-apps
agaudreault May 29, 2024
e1b605d
codegen
agaudreault May 29, 2024
a1e53c1
extract common code
agaudreault May 29, 2024
3a93268
use appset params in server
agaudreault May 29, 2024
ee3af96
codegen
agaudreault May 29, 2024
6789713
fix test build
agaudreault May 29, 2024
8b62d2c
unit tests
agaudreault May 29, 2024
7a62935
move test to new package
agaudreault May 30, 2024
0938382
move to correct folders
agaudreault May 30, 2024
92dd08e
fix build
agaudreault May 30, 2024
327d57b
review
agaudreault May 30, 2024
a501a39
Merge branch 'master' into appset-list-apps
agaudreault May 30, 2024
3a9a4f2
Merge remote-tracking branch 'origin/master' into appset-list-apps
crenshaw-dev Jun 17, 2024
fbec379
lint
crenshaw-dev Jun 17, 2024
5e85cdd
fix test
crenshaw-dev Jun 17, 2024
923301f
Merge remote-tracking branch 'origin/master' into appset-list-apps
crenshaw-dev Jun 17, 2024
f151adf
fix lint
crenshaw-dev Jun 17, 2024
45676f4
auto generate mocks
crenshaw-dev Jun 17, 2024
93268f9
better error handling
crenshaw-dev Jun 17, 2024
1c41029
more docs
crenshaw-dev Jun 17, 2024
19b0871
more docs
crenshaw-dev Jun 17, 2024
02bb52a
lint
crenshaw-dev Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 5 additions & 141 deletions applicationset/controllers/applicationset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"

"github.com/argoproj/argo-cd/v2/applicationset/controllers/template"
"github.com/argoproj/argo-cd/v2/applicationset/generators"
"github.com/argoproj/argo-cd/v2/applicationset/status"
"github.com/argoproj/argo-cd/v2/applicationset/utils"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/db"
Expand Down Expand Up @@ -129,7 +131,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Log a warning if there are unrecognized generators
_ = utils.CheckInvalidGenerators(&applicationSetInfo)
// desiredApplications is the main list of all expected Applications from all generators in this appset.
desiredApplications, applicationSetReason, generatorsErr := r.generateApplications(logCtx, applicationSetInfo)
desiredApplications, applicationSetReason, generatorsErr := template.GenerateApplications(logCtx, applicationSetInfo, r.Generators, r.Renderer, r.Client)
if generatorsErr != nil {
_ = r.setApplicationSetStatusCondition(ctx,
&applicationSetInfo,
Expand Down Expand Up @@ -495,88 +497,6 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argov1
return res
}

func getTempApplication(applicationSetTemplate argov1alpha1.ApplicationSetTemplate) *argov1alpha1.Application {
var tmplApplication argov1alpha1.Application
tmplApplication.Annotations = applicationSetTemplate.Annotations
tmplApplication.Labels = applicationSetTemplate.Labels
tmplApplication.Namespace = applicationSetTemplate.Namespace
tmplApplication.Name = applicationSetTemplate.Name
tmplApplication.Spec = applicationSetTemplate.Spec
tmplApplication.Finalizers = applicationSetTemplate.Finalizers

return &tmplApplication
}

func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, argov1alpha1.ApplicationSetReasonType, error) {
var res []argov1alpha1.Application

var firstError error
var applicationSetReason argov1alpha1.ApplicationSetReasonType

for _, requestedGenerator := range applicationSetInfo.Spec.Generators {
t, err := generators.Transform(requestedGenerator, r.Generators, applicationSetInfo.Spec.Template, &applicationSetInfo, map[string]interface{}{}, r.Client)
if err != nil {
logCtx.WithError(err).WithField("generator", requestedGenerator).
Error("error generating application from params")
if firstError == nil {
firstError = err
applicationSetReason = argov1alpha1.ApplicationSetReasonApplicationParamsGenerationError
}
continue
}

for _, a := range t {
tmplApplication := getTempApplication(a.Template)

for _, p := range a.Params {
app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions)
if err != nil {
logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator).
Error("error generating application from params")

if firstError == nil {
firstError = err
applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError
}
continue
}

if applicationSetInfo.Spec.TemplatePatch != nil {
patchedApplication, err := r.applyTemplatePatch(app, applicationSetInfo, p)
if err != nil {
log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator).
Error("error generating application from params")

if firstError == nil {
firstError = err
applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError
}
continue
}

app = patchedApplication
}

res = append(res, *app)
}
}

logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res))
logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res)
}

return res, applicationSetReason, firstError
}

func (r *ApplicationSetReconciler) applyTemplatePatch(app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]interface{}) (*argov1alpha1.Application, error) {
replacedTemplate, err := r.Renderer.Replace(*applicationSetInfo.Spec.TemplatePatch, params, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions)
if err != nil {
return nil, fmt.Errorf("error replacing values in templatePatch: %w", err)
}

return applyTemplatePatch(app, replacedTemplate)
}

func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
Expand Down Expand Up @@ -650,10 +570,6 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
var firstError error
// Creates or updates the application in appList
for _, generatedApp := range desiredApplications {
// The app's namespace must be the same as the AppSet's namespace to preserve the appsets-in-any-namespace
// security boundary.
generatedApp.Namespace = applicationSet.Namespace

appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()})

// Normalize to avoid fighting with the application controller.
Expand Down Expand Up @@ -1351,8 +1267,8 @@ func findApplicationStatusIndex(appStatuses []argov1alpha1.ApplicationSetApplica
}

func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, logCtx *log.Entry, appset *argov1alpha1.ApplicationSet, apps []argov1alpha1.Application) error {
statusMap := getResourceStatusMap(appset)
statusMap = buildResourceStatus(statusMap, apps)
statusMap := status.GetResourceStatusMap(appset)
statusMap = status.BuildResourceStatus(statusMap, apps)

statuses := []argov1alpha1.ResourceStatus{}
for _, status := range statusMap {
Expand All @@ -1377,58 +1293,6 @@ func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, lo
return nil
}

func buildResourceStatus(statusMap map[string]argov1alpha1.ResourceStatus, apps []argov1alpha1.Application) map[string]argov1alpha1.ResourceStatus {
appMap := map[string]argov1alpha1.Application{}
for _, app := range apps {
appCopy := app
appMap[app.Name] = app

gvk := app.GroupVersionKind()
// Create status if it does not exist
status, ok := statusMap[app.Name]
if !ok {
status = argov1alpha1.ResourceStatus{
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
Name: app.Name,
Namespace: app.Namespace,
Status: app.Status.Sync.Status,
Health: &appCopy.Status.Health,
}
}

status.Group = gvk.Group
status.Version = gvk.Version
status.Kind = gvk.Kind
status.Name = app.Name
status.Namespace = app.Namespace
status.Status = app.Status.Sync.Status
status.Health = &appCopy.Status.Health

statusMap[app.Name] = status
}
cleanupDeletedApplicationStatuses(statusMap, appMap)

return statusMap
}

func getResourceStatusMap(appset *argov1alpha1.ApplicationSet) map[string]argov1alpha1.ResourceStatus {
statusMap := map[string]argov1alpha1.ResourceStatus{}
for _, status := range appset.Status.Resources {
statusMap[status.Name] = status
}
return statusMap
}

func cleanupDeletedApplicationStatuses(statusMap map[string]argov1alpha1.ResourceStatus, apps map[string]argov1alpha1.Application) {
for name := range statusMap {
if _, ok := apps[name]; !ok {
delete(statusMap, name)
}
}
}

// setApplicationSetApplicationStatus updates the ApplicationSet's status field
// with any new/changed Application statuses.
func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, applicationStatuses []argov1alpha1.ApplicationSetApplicationStatus) error {
Expand Down
Loading