Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nabuskey committed May 29, 2024
1 parent deb5e10 commit 3e29354
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 59 deletions.
247 changes: 188 additions & 59 deletions pkg/controllers/custompackage/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (r *Reconciler) postProcessReconcile(ctx context.Context, req ctrl.Request,
func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alpha1.CustomPackage) (ctrl.Result, error) {
b, err := r.getArgoCDAppFile(ctx, resource)
if err != nil {
return ctrl.Result{}, fmt.Errorf("reading file %s: %w", resource.Spec.ArgoCD.ApplicationFile, err)
return ctrl.Result{}, fmt.Errorf("reading file %s%s: %w", resource.Spec.ArgoCD.ApplicationFile, resource.Spec.ArgoCD.ApplicationSetFile, err)
}

var returnedRawResource []byte
Expand All @@ -91,59 +91,161 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
return ctrl.Result{}, fmt.Errorf("file contained 0 kubernetes objects %s", resource.Spec.ArgoCD.ApplicationFile)
}

var appSpec *argov1alpha1.ApplicationSpec
var app client.Object

switch resource.Spec.ArgoCD.Type {
case argocdapplication.ApplicationKind:
a, ok := objs[0].(*argov1alpha1.Application)
app, ok := objs[0].(*argov1alpha1.Application)
if !ok {
return ctrl.Result{}, fmt.Errorf("object is not an ArgoCD application %s", resource.Spec.ArgoCD.ApplicationFile)
}
appSpec = &a.Spec

res, err := r.reconcileArgoCDApp(ctx, resource, app)
if err != nil {
return ctrl.Result{}, err
}

foundAppObj := argov1alpha1.Application{}
err = r.Client.Get(ctx, client.ObjectKeyFromObject(app), &foundAppObj)
if err != nil {
if errors.IsNotFound(err) {
err = r.Client.Create(ctx, app)
if err != nil {
return ctrl.Result{}, fmt.Errorf("creating %s app CR: %w", app.Name, err)
}

return ctrl.Result{RequeueAfter: requeueTime}, nil
}
return ctrl.Result{}, fmt.Errorf("getting argocd application object: %w", err)
}

foundAppObj.Spec = app.Spec
foundAppObj.ObjectMeta.Annotations = app.GetAnnotations()
foundAppObj.ObjectMeta.Labels = app.GetLabels()
err = r.Client.Update(ctx, &foundAppObj)
if err != nil {
return ctrl.Result{}, fmt.Errorf("updating argocd application object %s: %w", app.Name, err)
}
return res, nil

case argocdapplication.ApplicationSetKind:
{
a, ok := objs[0].(*argov1alpha1.ApplicationSet)
if !ok {
return ctrl.Result{}, fmt.Errorf("object is not an ArgoCD application set %s", resource.Spec.ArgoCD.ApplicationSetFile)
// application set embeds application spec. extract it then handle git generator repoURLs.
appSet, ok := objs[0].(*argov1alpha1.ApplicationSet)
if !ok {
return ctrl.Result{}, fmt.Errorf("object is not an ArgoCD application set %s", resource.Spec.ArgoCD.ApplicationSetFile)
}
res, err := r.reconcileArgoCDAppSet(ctx, resource, appSet)
if err != nil {
return ctrl.Result{}, err
}
foundAppSetObj := argov1alpha1.ApplicationSet{}
err = r.Client.Get(ctx, client.ObjectKeyFromObject(appSet), &foundAppSetObj)
if err != nil {
if errors.IsNotFound(err) {
err = r.Client.Create(ctx, appSet)
if err != nil {
return ctrl.Result{}, fmt.Errorf("creating %s argocd application set CR: %w", appSet.Name, err)
}
return ctrl.Result{RequeueAfter: requeueTime}, nil
}
appSpec = &a.Spec.Template.Spec
return ctrl.Result{}, fmt.Errorf("getting argocd application set object: %w", err)
}

foundAppSetObj.Spec = appSet.Spec
foundAppSetObj.ObjectMeta.Annotations = appSet.GetAnnotations()
foundAppSetObj.ObjectMeta.Labels = appSet.GetLabels()
err = r.Client.Update(ctx, &foundAppSetObj)
if err != nil {
return ctrl.Result{}, fmt.Errorf("updating argocd application object %s: %w", appSet.Name, err)
}
return res, nil

default:
return ctrl.Result{}, fmt.Errorf("file is not a supported argocd kind %s %s", resource.Spec.ArgoCD.ApplicationFile, resource.Spec.ArgoCD.ApplicationSetFile)
}

appName := app.GetName()
if resource.Spec.Replicate {
synced := true
repoRefs := make([]v1alpha1.ObjectRef, 0, 1)
if appSpec.HasMultipleSources() {
for j := range appSpec.Sources {
s := &appSpec.Sources[j]
res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s, appName)
if sErr != nil {
return res, sErr
}
if repo != nil {
if synced {
synced = repo.Status.InternalGitRepositoryUrl != ""
}
s.RepoURL = repo.Status.InternalGitRepositoryUrl
repoRefs = append(repoRefs, v1alpha1.ObjectRef{
Namespace: repo.Namespace,
Name: repo.Name,
UID: string(repo.ObjectMeta.UID),
})
}
}
} else {
s := appSpec.Source
res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s, appName)
//appName := app.GetName()
//if resource.Spec.Replicate {
// appSourcesSynced := false
// repoRefs := make([]v1alpha1.ObjectRef, 0, 1)
// if appSpec.HasMultipleSources() {
// notSyncedRepos := 0
// for j := range appSpec.Sources {
// s := &appSpec.Sources[j]
// res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s.RepoURL, appName)
// if sErr != nil {
// return res, sErr
// }
// if repo != nil {
// if repo.Status.InternalGitRepositoryUrl == "" {
// notSyncedRepos += 1
// }
// s.RepoURL = repo.Status.InternalGitRepositoryUrl
// repoRefs = append(repoRefs, v1alpha1.ObjectRef{
// Namespace: repo.Namespace,
// Name: repo.Name,
// UID: string(repo.ObjectMeta.UID),
// })
// }
// }
// appSourcesSynced = notSyncedRepos == 0
// } else {
// s := appSpec.Source
// res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s.RepoURL, appName)
// if sErr != nil {
// return res, sErr
// }
// if repo != nil {
// appSourcesSynced = repo.Status.InternalGitRepositoryUrl != ""
// s.RepoURL = repo.Status.InternalGitRepositoryUrl
// repoRefs = append(repoRefs, v1alpha1.ObjectRef{
// Namespace: repo.Namespace,
// Name: repo.Name,
// UID: string(repo.ObjectMeta.UID),
// })
// }
// }
// resource.Status.GitRepositoryRefs = repoRefs
// resource.Status.Synced = appSourcesSynced && gitGeneratorsSynced
//}
//
//foundAppObj := argov1alpha1.Application{}
//err = r.Client.Get(ctx, client.ObjectKeyFromObject(app), &foundAppObj)
//if err != nil {
// if errors.IsNotFound(err) {
// err = r.Client.Create(ctx, app)
// if err != nil {
// return ctrl.Result{}, fmt.Errorf("creating %s app CR: %w", appName, err)
// }
//
// return ctrl.Result{RequeueAfter: requeueTime}, nil
// }
// return ctrl.Result{}, fmt.Errorf("getting argocd application object: %w", err)
//}
//
//foundAppObj.Spec = *appSpec
//foundAppObj.ObjectMeta.Annotations = app.GetAnnotations()
//foundAppObj.ObjectMeta.Labels = app.GetLabels()
//err = r.Client.Update(ctx, &foundAppObj)
//if err != nil {
// return ctrl.Result{}, fmt.Errorf("updating argocd application object %s: %w", appName, err)
//}
//return ctrl.Result{RequeueAfter: requeueTime}, nil
}

func (r *Reconciler) reconcileArgoCDApp(ctx context.Context, resource *v1alpha1.CustomPackage, app *argov1alpha1.Application) (ctrl.Result, error) {
appSourcesSynced := false
repoRefs := make([]v1alpha1.ObjectRef, 0, 1)
if app.Spec.HasMultipleSources() {
notSyncedRepos := 0
for j := range app.Spec.Sources {
s := &app.Spec.Sources[j]
res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s.RepoURL, app.Name)
if sErr != nil {
return res, sErr
}
if repo != nil {
synced = repo.Status.InternalGitRepositoryUrl != ""
if repo.Status.InternalGitRepositoryUrl == "" {
notSyncedRepos += 1
}
s.RepoURL = repo.Status.InternalGitRepositoryUrl
repoRefs = append(repoRefs, v1alpha1.ObjectRef{
Namespace: repo.Namespace,
Expand All @@ -152,41 +254,68 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
})
}
}
resource.Status.GitRepositoryRefs = repoRefs
resource.Status.Synced = synced
appSourcesSynced = notSyncedRepos == 0
} else {
s := app.Spec.Source
res, repo, sErr := r.reconcileArgoCDSource(ctx, resource, s.RepoURL, app.Name)
if sErr != nil {
return res, sErr
}
if repo != nil {
appSourcesSynced = repo.Status.InternalGitRepositoryUrl != ""
s.RepoURL = repo.Status.InternalGitRepositoryUrl
repoRefs = append(repoRefs, v1alpha1.ObjectRef{
Namespace: repo.Namespace,
Name: repo.Name,
UID: string(repo.ObjectMeta.UID),
})
}
}
resource.Status.GitRepositoryRefs = repoRefs
resource.Status.Synced = appSourcesSynced
return ctrl.Result{RequeueAfter: requeueTime}, nil
}

foundAppObj := argov1alpha1.Application{}
err = r.Client.Get(ctx, client.ObjectKeyFromObject(app), &foundAppObj)
if err != nil {
if errors.IsNotFound(err) {
err = r.Client.Create(ctx, app)
if err != nil {
return ctrl.Result{}, fmt.Errorf("creating %s app CR: %w", appName, err)
func (r *Reconciler) reconcileArgoCDAppSet(ctx context.Context, resource *v1alpha1.CustomPackage, appSet *argov1alpha1.ApplicationSet) (ctrl.Result, error) {
notSyncedRepos := 0
for i := range appSet.Spec.Generators {
g := appSet.Spec.Generators[i]
if g.Git != nil {
res, repo, gErr := r.reconcileArgoCDSource(ctx, resource, g.Git.RepoURL, appSet.GetName())
if gErr != nil {
return res, fmt.Errorf("reconciling git generator URL %s, %s", g.Git.RepoURL, resource.Spec.ArgoCD.ApplicationSetFile)
}
if repo != nil {
g.Git.RepoURL = repo.Status.InternalGitRepositoryUrl
if repo.Status.InternalGitRepositoryUrl == "" {
notSyncedRepos += 1
}
}

return ctrl.Result{RequeueAfter: requeueTime}, nil
}
return ctrl.Result{}, fmt.Errorf("getting argocd application object: %w", err)
}

foundAppObj.Spec = *appSpec
foundAppObj.ObjectMeta.Annotations = app.GetAnnotations()
foundAppObj.ObjectMeta.Labels = app.GetLabels()
err = r.Client.Update(ctx, &foundAppObj)
gitGeneratorsSynced := notSyncedRepos == 0
app := argov1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{Name: appSet.GetName(), Namespace: appSet.Namespace},
}

_, err := r.reconcileArgoCDApp(ctx, resource, &app)
if err != nil {
return ctrl.Result{}, fmt.Errorf("updating argocd application object %s: %w", appName, err)
return ctrl.Result{}, fmt.Errorf("reconciling application set %s %w", resource.Spec.ArgoCD.ApplicationSetFile, err)
}

resource.Status.Synced = resource.Status.Synced && gitGeneratorsSynced

return ctrl.Result{RequeueAfter: requeueTime}, nil
}

// create a gitrepository custom resource, then let the git repository controller take care of the rest
func (r *Reconciler) reconcileArgoCDSource(ctx context.Context, resource *v1alpha1.CustomPackage, appSource *argov1alpha1.ApplicationSource, appName string) (ctrl.Result, *v1alpha1.GitRepository, error) {
if isCNOEScheme(appSource.RepoURL) {
func (r *Reconciler) reconcileArgoCDSource(ctx context.Context, resource *v1alpha1.CustomPackage, repoUrl, appName string) (ctrl.Result, *v1alpha1.GitRepository, error) {
if isCNOEScheme(repoUrl) {
if resource.Spec.RemoteRepository.Url == "" {
return r.reconcileArgoCDSourceFromLocal(ctx, resource, appName, appSource.RepoURL)
return r.reconcileArgoCDSourceFromLocal(ctx, resource, appName, repoUrl)
}
return r.reconcileArgoCDSourceFromRemote(ctx, resource, appName, appSource.RepoURL)
return r.reconcileArgoCDSourceFromRemote(ctx, resource, appName, repoUrl)
}
return ctrl.Result{}, nil, nil
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/controllers/custompackage/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func TestReconcileCustomPkg(t *testing.T) {
ApplicationFile: filepath.Join(cwd, "test/resources/customPackages/testDir/app.yaml"),
Name: "my-app",
Namespace: "argocd",
Type: "Application",
},
},
},
Expand All @@ -111,6 +112,7 @@ func TestReconcileCustomPkg(t *testing.T) {
ApplicationFile: filepath.Join(cwd, "test/resources/customPackages/testDir2/exampleApp.yaml"),
Name: "guestbook",
Namespace: "argocd",
Type: "Application",
},
},
},
Expand All @@ -128,6 +130,7 @@ func TestReconcileCustomPkg(t *testing.T) {
ApplicationFile: filepath.Join(cwd, "test/resources/customPackages/testDir/app2.yaml"),
Name: "my-app2",
Namespace: "argocd",
Type: "Application",
},
},
},
Expand Down

0 comments on commit 3e29354

Please sign in to comment.