Skip to content

Commit

Permalink
CR-4773 - add repo uninstall command (#122)
Browse files Browse the repository at this point in the history
* added `repo uninstall` command
  • Loading branch information
ATGardner authored Jul 5, 2021
1 parent 0dee45f commit d6eb87f
Show file tree
Hide file tree
Showing 21 changed files with 924 additions and 256 deletions.
24 changes: 5 additions & 19 deletions cmd/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"github.com/argoproj-labs/argocd-autopilot/pkg/application"
"github.com/argoproj-labs/argocd-autopilot/pkg/argocd"
"github.com/argoproj-labs/argocd-autopilot/pkg/fs"
"github.com/argoproj-labs/argocd-autopilot/pkg/git"
"github.com/argoproj-labs/argocd-autopilot/pkg/kube"
Expand Down Expand Up @@ -199,13 +198,14 @@ func RunAppCreate(ctx context.Context, opts *AppCreateOptions) error {

if opts.AppsCloneOpts != opts.CloneOpts {
log.G(ctx).Info("committing changes to apps repo...")
if err = appsRepo.Persist(ctx, &git.PushOptions{CommitMsg: getCommitMsg(opts, appsfs)}); err != nil {
if _, err = appsRepo.Persist(ctx, &git.PushOptions{CommitMsg: getCommitMsg(opts, appsfs)}); err != nil {
return fmt.Errorf("failed to push to apps repo: %w", err)
}
}

log.G(ctx).Info("committing changes to gitops repo...")
if err = r.Persist(ctx, &git.PushOptions{CommitMsg: getCommitMsg(opts, repofs)}); err != nil {
revision, err := r.Persist(ctx, &git.PushOptions{CommitMsg: getCommitMsg(opts, repofs)})
if err != nil {
return fmt.Errorf("failed to push to gitops repo: %w", err)
}

Expand All @@ -219,7 +219,7 @@ func RunAppCreate(ctx context.Context, opts *AppCreateOptions) error {
fullName := fmt.Sprintf("%s-%s", opts.ProjectName, opts.AppOpts.AppName)
// wait for argocd to be ready before applying argocd-apps
stop := util.WithSpinner(ctx, fmt.Sprintf("waiting for '%s' to be ready", fullName))
if err = waitAppSynced(ctx, opts.KubeFactory, opts.Timeout, fullName, namespace); err != nil {
if err = waitAppSynced(ctx, opts.KubeFactory, opts.Timeout, fullName, namespace, revision, true); err != nil {
stop()
return fmt.Errorf("failed waiting for application to sync: %w", err)
}
Expand Down Expand Up @@ -298,20 +298,6 @@ func getCommitMsg(opts *AppCreateOptions, repofs fs.FS) string {
return commitMsg
}

func waitAppSynced(ctx context.Context, f kube.Factory, timeout time.Duration, appName, namespace string) error {
return f.Wait(ctx, &kube.WaitOptions{
Interval: store.Default.WaitInterval,
Timeout: timeout,
Resources: []kube.Resource{
{
Name: appName,
Namespace: namespace,
WaitFunc: argocd.CheckAppSynced,
},
},
})
}

func NewAppListCommand(cloneOpts *git.CloneOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "list [PROJECT_NAME]",
Expand Down Expand Up @@ -490,7 +476,7 @@ func RunAppDelete(ctx context.Context, opts *AppDeleteOptions) error {
}

log.G(ctx).Info("committing changes to gitops repo...")
if err = r.Persist(ctx, &git.PushOptions{CommitMsg: commitMsg}); err != nil {
if _, err = r.Persist(ctx, &git.PushOptions{CommitMsg: commitMsg}); err != nil {
return fmt.Errorf("failed to push to repo: %w", err)
}

Expand Down
28 changes: 14 additions & 14 deletions cmd/commands/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(fmt.Errorf("some error"))
}).Return("", fmt.Errorf("some error"))
return mockRepo, fs.Create(memfs.New()), nil
},
},
Expand All @@ -129,7 +129,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(fmt.Errorf("some error"))
}).Return("", fmt.Errorf("some error"))
return mockRepo, fs.Create(memfs), nil
},
},
Expand All @@ -142,7 +142,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
getInstallationNamespace: func(repofs fs.FS) (string, error) {
Expand All @@ -161,7 +161,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
getInstallationNamespace: func(repofs fs.FS) (string, error) {
Expand All @@ -177,14 +177,14 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
getRepo: func(_ *testing.T, _ *git.CloneOptions) (git.Repository, fs.FS, error) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs.New()), nil
},
assertFn: func(t *testing.T, gitopsRepo git.Repository, appsRepo git.Repository) {
Expand All @@ -200,7 +200,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, gitopsRepo git.Repository, appsRepo git.Repository) {
Expand All @@ -219,7 +219,7 @@ func TestRunAppCreate(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "installed app 'app' on project 'project' installation-path: '/'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
getInstallationNamespace: func(repofs fs.FS) (string, error) {
Expand Down Expand Up @@ -462,7 +462,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand Down Expand Up @@ -506,7 +506,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app' from project 'project'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand All @@ -524,7 +524,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand All @@ -542,7 +542,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app' from project 'project'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand All @@ -560,7 +560,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app'",
}).Return(nil)
}).Return("revision", nil)
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand All @@ -578,7 +578,7 @@ func TestRunAppDelete(t *testing.T) {
mockRepo := &gitmocks.Repository{}
mockRepo.On("Persist", mock.Anything, &git.PushOptions{
CommitMsg: "Deleted app 'app'",
}).Return(fmt.Errorf("some error"))
}).Return("", fmt.Errorf("some error"))
return mockRepo, fs.Create(memfs), nil
},
assertFn: func(t *testing.T, repo git.Repository, repofs fs.FS) {
Expand Down
33 changes: 25 additions & 8 deletions cmd/commands/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
_ "embed"
"fmt"
"os"
"time"

"github.com/argoproj-labs/argocd-autopilot/pkg/argocd"
"github.com/argoproj-labs/argocd-autopilot/pkg/fs"
"github.com/argoproj-labs/argocd-autopilot/pkg/git"
"github.com/argoproj-labs/argocd-autopilot/pkg/kube"
"github.com/argoproj-labs/argocd-autopilot/pkg/log"
"github.com/argoproj-labs/argocd-autopilot/pkg/store"
"github.com/argoproj-labs/argocd-autopilot/pkg/util"
Expand Down Expand Up @@ -40,20 +43,20 @@ var (
}

prepareRepo = func(ctx context.Context, cloneOpts *git.CloneOptions, projectName string) (git.Repository, fs.FS, error) {
log.G().WithFields(log.Fields{
log.G(ctx).WithFields(log.Fields{
"repoURL": cloneOpts.URL(),
"revision": cloneOpts.Revision(),
}).Debug("starting with options: ")

// clone repo
log.G().Infof("cloning git repository: %s", cloneOpts.URL())
log.G(ctx).Infof("cloning git repository: %s", cloneOpts.URL())
r, repofs, err := getRepo(ctx, cloneOpts)
if err != nil {
return nil, nil, fmt.Errorf("Failed cloning the repository: %w", err)
}

root := repofs.Root()
log.G().Infof("using revision: \"%s\", installation path: \"%s\"", cloneOpts.Revision(), root)
log.G(ctx).Infof("using revision: \"%s\", installation path: \"%s\"", cloneOpts.Revision(), root)
if !repofs.ExistsOrDie(store.Default.BootsrtrapDir) {
return nil, nil, fmt.Errorf("Bootstrap directory not found, please execute `repo bootstrap` command")
}
Expand All @@ -65,7 +68,7 @@ var (
}
}

log.G().Debug("repository is ok")
log.G(ctx).Debug("repository is ok")

return r, repofs, nil
}
Expand Down Expand Up @@ -95,8 +98,8 @@ func createApp(opts *createAppOptions) ([]byte, error) {
Namespace: opts.namespace,
Name: opts.name,
Labels: map[string]string{
"app.kubernetes.io/managed-by": store.Default.ManagedBy,
"app.kubernetes.io/name": opts.name,
store.Default.LabelKeyAppManagedBy: store.Default.LabelValueManagedBy,
"app.kubernetes.io/name": opts.name,
},
Finalizers: []string{
"resources-finalizer.argocd.argoproj.io",
Expand Down Expand Up @@ -141,6 +144,20 @@ func createApp(opts *createAppOptions) ([]byte, error) {
return yaml.Marshal(app)
}

func waitAppSynced(ctx context.Context, f kube.Factory, timeout time.Duration, appName, namespace, revision string, waitForCreation bool) error {
return f.Wait(ctx, &kube.WaitOptions{
Interval: store.Default.WaitInterval,
Timeout: timeout,
Resources: []kube.Resource{
{
Name: appName,
Namespace: namespace,
WaitFunc: argocd.GetAppSyncWaitFunc(revision, waitForCreation),
},
},
})
}

type createAppSetOptions struct {
name string
namespace string
Expand Down Expand Up @@ -220,8 +237,8 @@ func createAppSet(o *createAppSetOptions) ([]byte, error) {
if o.appLabels == nil {
// default labels
appSet.Spec.Template.ApplicationSetTemplateMeta.Labels = map[string]string{
"app.kubernetes.io/managed-by": store.Default.ManagedBy,
"app.kubernetes.io/name": o.appName,
store.Default.LabelKeyAppManagedBy: store.Default.LabelValueManagedBy,
"app.kubernetes.io/name": o.appName,
}
}

Expand Down
30 changes: 16 additions & 14 deletions cmd/commands/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ func NewProjectCreateCommand(cloneOpts *git.CloneOptions) *cobra.Command {
`),
PreRun: func(_ *cobra.Command, _ []string) { cloneOpts.Parse() },
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if len(args) < 1 {
log.G().Fatal("must enter project name")
log.G(ctx).Fatal("must enter project name")
}

return RunProjectCreate(cmd.Context(), &ProjectCreateOptions{
return RunProjectCreate(ctx, &ProjectCreateOptions{
CloneOpts: cloneOpts,
ProjectName: args[0],
DestKubeContext: kubeContext,
Expand Down Expand Up @@ -152,7 +153,7 @@ func RunProjectCreate(ctx context.Context, opts *ProjectCreateOptions) error {
return fmt.Errorf("project '%s' already exists", opts.ProjectName)
}

log.G().Debug("repository is ok")
log.G(ctx).Debug("repository is ok")

destServer := store.Default.DestServer
if opts.DestKubeContext != "" {
Expand All @@ -176,14 +177,14 @@ func RunProjectCreate(ctx context.Context, opts *ProjectCreateOptions) error {
}

if opts.DryRun {
log.G().Printf("%s", util.JoinManifests(projectYAML, appsetYAML))
log.G(ctx).Printf("%s", util.JoinManifests(projectYAML, appsetYAML))
return nil
}

bulkWrites := []fsutils.BulkWriteRequest{}

if opts.DestKubeContext != "" {
log.G().Infof("adding cluster: %s", opts.DestKubeContext)
log.G(ctx).Infof("adding cluster: %s", opts.DestKubeContext)
if err = opts.AddCmd.Execute(ctx, opts.DestKubeContext); err != nil {
return fmt.Errorf("failed to add new cluster credentials: %w", err)
}
Expand Down Expand Up @@ -213,12 +214,12 @@ func RunProjectCreate(ctx context.Context, opts *ProjectCreateOptions) error {
return err
}

log.G().Infof("pushing new project manifest to repo")
if err = r.Persist(ctx, &git.PushOptions{CommitMsg: fmt.Sprintf("Added project '%s'", opts.ProjectName)}); err != nil {
log.G(ctx).Infof("pushing new project manifest to repo")
if _, err = r.Persist(ctx, &git.PushOptions{CommitMsg: fmt.Sprintf("Added project '%s'", opts.ProjectName)}); err != nil {
return err
}

log.G().Infof("project created: '%s'", opts.ProjectName)
log.G(ctx).Infof("project created: '%s'", opts.ProjectName)

return nil
}
Expand Down Expand Up @@ -280,8 +281,8 @@ func generateProjectManifests(o *GenerateProjectOptions) (projectYAML, appSetYAM
prune: true,
preserveResourcesOnDeletion: false,
appLabels: map[string]string{
"app.kubernetes.io/managed-by": store.Default.ManagedBy,
"app.kubernetes.io/name": "{{ appName }}",
store.Default.LabelKeyAppManagedBy: store.Default.LabelValueManagedBy,
"app.kubernetes.io/name": "{{ appName }}",
},
generators: []appset.ApplicationSetGenerator{
{
Expand Down Expand Up @@ -403,11 +404,12 @@ func NewProjectDeleteCommand(cloneOpts *git.CloneOptions) *cobra.Command {
`),
PreRun: func(_ *cobra.Command, _ []string) { cloneOpts.Parse() },
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if len(args) < 1 {
log.G().Fatal("must enter project name")
log.G(ctx).Fatal("must enter project name")
}

return RunProjectDelete(cmd.Context(), &ProjectDeleteOptions{
return RunProjectDelete(ctx, &ProjectDeleteOptions{
CloneOpts: cloneOpts,
ProjectName: args[0],
})
Expand Down Expand Up @@ -440,8 +442,8 @@ func RunProjectDelete(ctx context.Context, opts *ProjectDeleteOptions) error {
return fmt.Errorf("failed to delete project '%s': %w", opts.ProjectName, err)
}

log.G().Info("committing changes to gitops repo...")
if err = r.Persist(ctx, &git.PushOptions{CommitMsg: fmt.Sprintf("Deleted project '%s'", opts.ProjectName)}); err != nil {
log.G(ctx).Info("committing changes to gitops repo...")
if _, err = r.Persist(ctx, &git.PushOptions{CommitMsg: fmt.Sprintf("Deleted project '%s'", opts.ProjectName)}); err != nil {
return fmt.Errorf("failed to push to repo: %w", err)
}

Expand Down
Loading

0 comments on commit d6eb87f

Please sign in to comment.