From 329e21fd78d2cbcfac196f352029b3bbd2404b6e Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Thu, 25 Jun 2020 17:31:58 +0200 Subject: [PATCH] Create logger interface --- cmd/tk/bootstrap.go | 2 +- cmd/tk/bootstrap_github.go | 32 +++++++++++++++---------------- cmd/tk/bootstrap_gitlab.go | 28 +++++++++++++-------------- cmd/tk/check.go | 34 ++++++++++++++++----------------- cmd/tk/create_kustomization.go | 14 +++++++------- cmd/tk/create_source_git.go | 26 ++++++++++++------------- cmd/tk/delete_kustomization.go | 6 +++--- cmd/tk/delete_source_git.go | 4 ++-- cmd/tk/export_kustomization.go | 2 +- cmd/tk/export_source_git.go | 2 +- cmd/tk/get_kustomization.go | 12 ++++++------ cmd/tk/get_source_git.go | 8 ++++---- cmd/tk/install.go | 16 ++++++++-------- cmd/tk/log.go | 12 +++++++----- cmd/tk/main.go | 7 +++++-- cmd/tk/resume_kustomization.go | 10 +++++----- cmd/tk/suspend_kustomization.go | 4 ++-- cmd/tk/sync_kustomization.go | 10 +++++----- cmd/tk/sync_source_git.go | 10 +++++----- cmd/tk/uninstall.go | 8 ++++---- pkg/log/log.go | 29 ++++++++++++++++++++++++++++ 21 files changed, 155 insertions(+), 121 deletions(-) create mode 100644 pkg/log/log.go diff --git a/cmd/tk/bootstrap.go b/cmd/tk/bootstrap.go index b1376372..9f02ecfb 100644 --- a/cmd/tk/bootstrap.go +++ b/cmd/tk/bootstrap.go @@ -179,7 +179,7 @@ func applySyncManifests(ctx context.Context, kubeClient client.Client, name, nam return err } - logWaiting("waiting for cluster sync") + logger.Waitingf("waiting for cluster sync") if err := wait.PollImmediate(pollInterval, timeout, isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil { diff --git a/cmd/tk/bootstrap_github.go b/cmd/tk/bootstrap_github.go index 872c915e..bf455ab1 100644 --- a/cmd/tk/bootstrap_github.go +++ b/cmd/tk/bootstrap_github.go @@ -118,13 +118,13 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { defer cancel() // create GitHub repository if doesn't exists - logAction("connecting to %s", ghHostname) + logger.Actionf("connecting to %s", ghHostname) changed, err := provider.CreateRepository(ctx, repository) if err != nil { return err } if changed { - logSuccess("repository created") + logger.Successf("repository created") } withErrors := false @@ -132,10 +132,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if !ghPersonal { for _, team := range ghTeams { if changed, err := provider.AddTeam(ctx, repository, team, ghDefaultPermission); err != nil { - logFailure(err.Error()) + logger.Failuref(err.Error()) withErrors = true } else if changed { - logSuccess("%s team access granted", team) + logger.Successf("%s team access granted", team) } } } @@ -144,10 +144,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil { return err } - logSuccess("repository cloned") + logger.Successf("repository cloned") // generate install manifests - logGenerate("generating manifests") + logger.Generatef("generating manifests") manifest, err := generateInstallManifests(ghPath, namespace, tmpDir) if err != nil { return err @@ -164,9 +164,9 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if err := repository.Push(ctx); err != nil { return err } - logSuccess("components manifests pushed") + logger.Successf("components manifests pushed") } else { - logSuccess("components are up to date") + logger.Successf("components are up to date") } // determine if repo synchronization is working @@ -174,16 +174,16 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if isInstall { // apply install manifests - logAction("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", namespace) if err := applyInstallManifests(ctx, manifest, components); err != nil { return err } - logSuccess("install completed") + logger.Successf("install completed") } // setup SSH deploy key if shouldCreateDeployKey(ctx, kubeClient, namespace) { - logAction("configuring deploy key") + logger.Actionf("configuring deploy key") u, err := url.Parse(repository.GetSSH()) if err != nil { return fmt.Errorf("git URL parse failed: %w", err) @@ -202,14 +202,14 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { return err } else if changed { - logSuccess("deploy key configured") + logger.Successf("deploy key configured") } } // configure repo synchronization if isInstall { // generate source and kustomization manifests - logAction("generating sync manifests") + logger.Actionf("generating sync manifests") if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, ghPath, tmpDir, ghInterval); err != nil { return err } @@ -221,11 +221,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { if err := repository.Push(ctx); err != nil { return err } - logSuccess("sync manifests pushed") + logger.Successf("sync manifests pushed") } // apply manifests and waiting for sync - logAction("applying sync manifests") + logger.Actionf("applying sync manifests") if err := applySyncManifests(ctx, kubeClient, namespace, namespace, ghPath, tmpDir); err != nil { return err } @@ -235,6 +235,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("bootstrap completed with errors") } - logSuccess("bootstrap finished") + logger.Successf("bootstrap finished") return nil } diff --git a/cmd/tk/bootstrap_gitlab.go b/cmd/tk/bootstrap_gitlab.go index 10d4343e..9fd3af4b 100644 --- a/cmd/tk/bootstrap_gitlab.go +++ b/cmd/tk/bootstrap_gitlab.go @@ -109,23 +109,23 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { defer cancel() // create GitLab project if doesn't exists - logAction("connecting to %s", glHostname) + logger.Actionf("connecting to %s", glHostname) changed, err := provider.CreateRepository(ctx, repository) if err != nil { return err } if changed { - logSuccess("repository created") + logger.Successf("repository created") } // clone repository and checkout the master branch if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil { return err } - logSuccess("repository cloned") + logger.Successf("repository cloned") // generate install manifests - logGenerate("generating manifests") + logger.Generatef("generating manifests") manifest, err := generateInstallManifests(glPath, namespace, tmpDir) if err != nil { return err @@ -142,9 +142,9 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { if err := repository.Push(ctx); err != nil { return err } - logSuccess("components manifests pushed") + logger.Successf("components manifests pushed") } else { - logSuccess("components are up to date") + logger.Successf("components are up to date") } // determine if repo synchronization is working @@ -152,16 +152,16 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { if isInstall { // apply install manifests - logAction("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", namespace) if err := applyInstallManifests(ctx, manifest, components); err != nil { return err } - logSuccess("install completed") + logger.Successf("install completed") } // setup SSH deploy key if shouldCreateDeployKey(ctx, kubeClient, namespace) { - logAction("configuring deploy key") + logger.Actionf("configuring deploy key") u, err := url.Parse(repository.GetSSH()) if err != nil { return fmt.Errorf("git URL parse failed: %w", err) @@ -180,14 +180,14 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { return err } else if changed { - logSuccess("deploy key configured") + logger.Successf("deploy key configured") } } // configure repo synchronization if isInstall { // generate source and kustomization manifests - logAction("generating sync manifests") + logger.Actionf("generating sync manifests") if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, glPath, tmpDir, glInterval); err != nil { return err } @@ -199,16 +199,16 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { if err := repository.Push(ctx); err != nil { return err } - logSuccess("sync manifests pushed") + logger.Successf("sync manifests pushed") } // apply manifests and waiting for sync - logAction("applying sync manifests") + logger.Actionf("applying sync manifests") if err := applySyncManifests(ctx, kubeClient, namespace, namespace, glPath, tmpDir); err != nil { return err } } - logSuccess("bootstrap finished") + logger.Successf("bootstrap finished") return nil } diff --git a/cmd/tk/check.go b/cmd/tk/check.go index 18492137..ca26f972 100644 --- a/cmd/tk/check.go +++ b/cmd/tk/check.go @@ -58,7 +58,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - logAction("checking prerequisites") + logger.Actionf("checking prerequisites") checkFailed := false if !kubectlCheck(ctx, ">=1.18.0") { @@ -73,83 +73,83 @@ func runCheckCmd(cmd *cobra.Command, args []string) error { if checkFailed { os.Exit(1) } - logSuccess("prerequisites checks passed") + logger.Successf("prerequisites checks passed") return nil } - logAction("checking controllers") + logger.Actionf("checking controllers") if !componentsCheck() { checkFailed = true } if checkFailed { os.Exit(1) } - logSuccess("all checks passed") + logger.Successf("all checks passed") return nil } func kubectlCheck(ctx context.Context, version string) bool { _, err := exec.LookPath("kubectl") if err != nil { - logFailure("kubectl not found") + logger.Failuref("kubectl not found") return false } command := "kubectl version --client --short | awk '{ print $3 }'" output, err := utils.execCommand(ctx, ModeCapture, command) if err != nil { - logFailure("kubectl version can't be determined") + logger.Failuref("kubectl version can't be determined") return false } v, err := semver.ParseTolerant(output) if err != nil { - logFailure("kubectl version can't be parsed") + logger.Failuref("kubectl version can't be parsed") return false } rng, _ := semver.ParseRange(version) if !rng(v) { - logFailure("kubectl version must be %s", version) + logger.Failuref("kubectl version must be %s", version) return false } - logSuccess("kubectl %s %s", v.String(), version) + logger.Successf("kubectl %s %s", v.String(), version) return true } func kubernetesCheck(version string) bool { cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { - logFailure("Kubernetes client initialization failed: %s", err.Error()) + logger.Failuref("Kubernetes client initialization failed: %s", err.Error()) return false } client, err := kubernetes.NewForConfig(cfg) if err != nil { - logFailure("Kubernetes client initialization failed: %s", err.Error()) + logger.Failuref("Kubernetes client initialization failed: %s", err.Error()) return false } ver, err := client.Discovery().ServerVersion() if err != nil { - logFailure("Kubernetes API call failed: %s", err.Error()) + logger.Failuref("Kubernetes API call failed: %s", err.Error()) return false } v, err := semver.ParseTolerant(ver.String()) if err != nil { - logFailure("Kubernetes version can't be determined") + logger.Failuref("Kubernetes version can't be determined") return false } rng, _ := semver.ParseRange(version) if !rng(v) { - logFailure("Kubernetes version must be %s", version) + logger.Failuref("Kubernetes version must be %s", version) return false } - logSuccess("Kubernetes %s %s", v.String(), version) + logger.Successf("Kubernetes %s %s", v.String(), version) return true } @@ -162,10 +162,10 @@ func componentsCheck() bool { command := fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s", namespace, deployment, timeout.String()) if output, err := utils.execCommand(ctx, ModeCapture, command); err != nil { - logFailure("%s: %s", deployment, strings.TrimSuffix(output, "\n")) + logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n")) ok = false } else { - logSuccess("%s is healthy", deployment) + logger.Successf("%s is healthy", deployment) } } return ok diff --git a/cmd/tk/create_kustomization.go b/cmd/tk/create_kustomization.go index 6bb9da7a..2319eea9 100644 --- a/cmd/tk/create_kustomization.go +++ b/cmd/tk/create_kustomization.go @@ -122,7 +122,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { } if !export { - logGenerate("generating kustomization") + logger.Generatef("generating kustomization") } emptyAPIGroup := "" @@ -192,18 +192,18 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { return exportKs(kustomization) } - logAction("applying kustomization") + logger.Actionf("applying kustomization") if err := upsertKustomization(ctx, kubeClient, kustomization); err != nil { return err } - logWaiting("waiting for kustomization sync") + logger.Waitingf("waiting for kustomization sync") if err := wait.PollImmediate(pollInterval, timeout, isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil { return err } - logSuccess("kustomization %s is ready", name) + logger.Successf("kustomization %s is ready", name) namespacedName := types.NamespacedName{ Namespace: namespace, @@ -215,7 +215,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { } if kustomization.Status.LastAppliedRevision != "" { - logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision) + logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision) } else { return fmt.Errorf("kustomization sync failed") } @@ -236,7 +236,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz if err := kubeClient.Create(ctx, &kustomization); err != nil { return err } else { - logSuccess("kustomization created") + logger.Successf("kustomization created") return nil } } @@ -248,7 +248,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz return err } - logSuccess("kustomization updated") + logger.Successf("kustomization updated") return nil } diff --git a/cmd/tk/create_source_git.go b/cmd/tk/create_source_git.go index 3276ce64..b7fa8fdc 100644 --- a/cmd/tk/create_source_git.go +++ b/cmd/tk/create_source_git.go @@ -166,7 +166,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { withAuth := false // TODO(hidde): move all auth prep to separate func? if u.Scheme == "ssh" { - logAction("generating deploy key pair") + logger.Actionf("generating deploy key pair") pair, err := generateKeyPair(ctx) if err != nil { return err @@ -181,15 +181,15 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("aborting") } - logAction("collecting preferred public key from SSH server") + logger.Actionf("collecting preferred public key from SSH server") hostKey, err := scanHostKey(ctx, u) if err != nil { return err } - logSuccess("collected public key from SSH server:") + logger.Successf("collected public key from SSH server:") fmt.Printf("%s", hostKey) - logAction("applying secret with keys") + logger.Actionf("applying secret with keys") secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -206,7 +206,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } withAuth = true } else if sourceGitUsername != "" && sourceGitPassword != "" { - logAction("applying secret with basic auth credentials") + logger.Actionf("applying secret with basic auth credentials") secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -224,10 +224,10 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if withAuth { - logSuccess("authentication configured") + logger.Successf("authentication configured") } - logGenerate("generating source") + logger.Generatef("generating source") if withAuth { gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{ @@ -235,18 +235,18 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } } - logAction("applying source") + logger.Actionf("applying source") if err := upsertGitRepository(ctx, kubeClient, gitRepository); err != nil { return err } - logWaiting("waiting for git sync") + logger.Waitingf("waiting for git sync") if err := wait.PollImmediate(pollInterval, timeout, isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil { return err } - logSuccess("git sync completed") + logger.Successf("git sync completed") namespacedName := types.NamespacedName{ Namespace: namespace, @@ -258,7 +258,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if gitRepository.Status.Artifact != nil { - logSuccess("fetched revision: %s", gitRepository.Status.Artifact.Revision) + logger.Successf("fetched revision: %s", gitRepository.Status.Artifact.Revision) } else { return fmt.Errorf("git sync failed, artifact not found") } @@ -336,7 +336,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos if err := kubeClient.Create(ctx, &gitRepository); err != nil { return err } else { - logSuccess("source created") + logger.Successf("source created") return nil } } @@ -348,7 +348,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos return err } - logSuccess("source updated") + logger.Successf("source updated") return nil } diff --git a/cmd/tk/delete_kustomization.go b/cmd/tk/delete_kustomization.go index 28d326b6..d72bf186 100644 --- a/cmd/tk/delete_kustomization.go +++ b/cmd/tk/delete_kustomization.go @@ -65,7 +65,7 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error { if !deleteSilent { if !kustomization.Spec.Suspend { - logWaiting("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name) + logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name) } prompt := promptui.Prompt{ Label: "Are you sure you want to delete this kustomization", @@ -76,12 +76,12 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error { } } - logAction("deleting kustomization %s in %s namespace", name, namespace) + logger.Actionf("deleting kustomization %s in %s namespace", name, namespace) err = kubeClient.Delete(ctx, &kustomization) if err != nil { return err } - logSuccess("kustomization deleted") + logger.Successf("kustomization deleted") return nil } diff --git a/cmd/tk/delete_source_git.go b/cmd/tk/delete_source_git.go index f88ab69c..cbb4f092 100644 --- a/cmd/tk/delete_source_git.go +++ b/cmd/tk/delete_source_git.go @@ -72,12 +72,12 @@ func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error { } } - logAction("deleting source %s in %s namespace", name, namespace) + logger.Actionf("deleting source %s in %s namespace", name, namespace) err = kubeClient.Delete(ctx, &git) if err != nil { return err } - logSuccess("source deleted") + logger.Successf("source deleted") return nil } diff --git a/cmd/tk/export_kustomization.go b/cmd/tk/export_kustomization.go index 83c2a633..17fc2800 100644 --- a/cmd/tk/export_kustomization.go +++ b/cmd/tk/export_kustomization.go @@ -67,7 +67,7 @@ func exportKsCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logFailure("no kustomizations found in %s namespace", namespace) + logger.Failuref("no kustomizations found in %s namespace", namespace) return nil } diff --git a/cmd/tk/export_source_git.go b/cmd/tk/export_source_git.go index 714a8a1a..6b8dafa8 100644 --- a/cmd/tk/export_source_git.go +++ b/cmd/tk/export_source_git.go @@ -67,7 +67,7 @@ func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logFailure("no source found in %s namespace", namespace) + logger.Failuref("no source found in %s namespace", namespace) return nil } diff --git a/cmd/tk/get_kustomization.go b/cmd/tk/get_kustomization.go index 5e09a8cb..f53d9600 100644 --- a/cmd/tk/get_kustomization.go +++ b/cmd/tk/get_kustomization.go @@ -53,13 +53,13 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logFailure("no kustomizations found in %s namespace", namespace) + logger.Failuref("no kustomizations found in %s namespace", namespace) return nil } for _, kustomization := range list.Items { if kustomization.Spec.Suspend { - logSuccess("%s is suspended", kustomization.GetName()) + logger.Successf("%s is suspended", kustomization.GetName()) continue } isInitialized := false @@ -67,19 +67,19 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error { if condition.Type == kustomizev1.ReadyCondition { if condition.Status != corev1.ConditionFalse { if kustomization.Status.LastAppliedRevision != "" { - logSuccess("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision) + logger.Successf("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision) } else { - logSuccess("%s reconciling", kustomization.GetName()) + logger.Successf("%s reconciling", kustomization.GetName()) } } else { - logFailure("%s %s", kustomization.GetName(), condition.Message) + logger.Failuref("%s %s", kustomization.GetName(), condition.Message) } isInitialized = true break } } if !isInitialized { - logFailure("%s is not ready", kustomization.GetName()) + logger.Failuref("%s is not ready", kustomization.GetName()) } } return nil diff --git a/cmd/tk/get_source_git.go b/cmd/tk/get_source_git.go index 7fe82ef3..f490b66d 100644 --- a/cmd/tk/get_source_git.go +++ b/cmd/tk/get_source_git.go @@ -52,7 +52,7 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logFailure("no sources found in %s namespace", namespace) + logger.Failuref("no sources found in %s namespace", namespace) return nil } @@ -61,16 +61,16 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { for _, condition := range source.Status.Conditions { if condition.Type == sourcev1.ReadyCondition { if condition.Status != corev1.ConditionFalse { - logSuccess("%s last fetched revision: %s", source.GetName(), source.Status.Artifact.Revision) + logger.Successf("%s last fetched revision: %s", source.GetName(), source.Status.Artifact.Revision) } else { - logFailure("%s %s", source.GetName(), condition.Message) + logger.Failuref("%s %s", source.GetName(), condition.Message) } isInitialized = true break } } if !isInitialized { - logFailure("%s is not ready", source.GetName()) + logger.Failuref("%s is not ready", source.GetName()) } } return nil diff --git a/cmd/tk/install.go b/cmd/tk/install.go index 08c81d7e..8cbbf716 100644 --- a/cmd/tk/install.go +++ b/cmd/tk/install.go @@ -81,7 +81,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } defer os.RemoveAll(tmpDir) - logGenerate("generating manifests") + logger.Generatef("generating manifests") if kustomizePath == "" { err = genInstallManifests(installVersion, namespace, components, tmpDir) if err != nil { @@ -103,9 +103,9 @@ func installCmdRun(cmd *cobra.Command, args []string) error { fmt.Print(yaml) } } - logSuccess("manifests build completed") + logger.Successf("manifests build completed") - logAction("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", namespace) applyOutput := ModeStderrOS if verbose { applyOutput = ModeOS @@ -121,24 +121,24 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } if installDryRun { - logSuccess("install dry-run finished") + logger.Successf("install dry-run finished") return nil } else { - logSuccess("install completed") + logger.Successf("install completed") } - logWaiting("verifying installation") + logger.Waitingf("verifying installation") for _, deployment := range components { command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s", namespace, deployment, timeout.String()) if _, err := utils.execCommand(ctx, applyOutput, command); err != nil { return fmt.Errorf("install failed") } else { - logSuccess("%s ready", deployment) + logger.Successf("%s ready", deployment) } } - logSuccess("install finished") + logger.Successf("install finished") return nil } diff --git a/cmd/tk/log.go b/cmd/tk/log.go index 7ff5c329..984d18d1 100644 --- a/cmd/tk/log.go +++ b/cmd/tk/log.go @@ -18,22 +18,24 @@ package main import "fmt" -func logAction(format string, a ...interface{}) { +type printLogger struct{} + +func (l printLogger) Actionf(format string, a ...interface{}) { fmt.Println(`►`, fmt.Sprintf(format, a...)) } -func logGenerate(format string, a ...interface{}) { +func (l printLogger) Generatef(format string, a ...interface{}) { fmt.Println(`✚`, fmt.Sprintf(format, a...)) } -func logWaiting(format string, a ...interface{}) { +func (l printLogger) Waitingf(format string, a ...interface{}) { fmt.Println(`◎`, fmt.Sprintf(format, a...)) } -func logSuccess(format string, a ...interface{}) { +func (l printLogger) Successf(format string, a ...interface{}) { fmt.Println(`✔`, fmt.Sprintf(format, a...)) } -func logFailure(format string, a ...interface{}) { +func (l printLogger) Failuref(format string, a ...interface{}) { fmt.Println(`✗`, fmt.Sprintf(format, a...)) } diff --git a/cmd/tk/main.go b/cmd/tk/main.go index f1886122..a25d1fb9 100644 --- a/cmd/tk/main.go +++ b/cmd/tk/main.go @@ -25,6 +25,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/cobra/doc" _ "k8s.io/client-go/plugin/pkg/client/auth" + + tklog "github.com/fluxcd/toolkit/pkg/log" ) var VERSION = "0.0.0-dev.0" @@ -98,7 +100,8 @@ var ( verbose bool components []string utils Utils - pollInterval = 2 * time.Second + pollInterval = 2 * time.Second + logger tklog.Logger = printLogger{} ) func init() { @@ -118,7 +121,7 @@ func main() { generateDocs() kubeconfigFlag() if err := rootCmd.Execute(); err != nil { - logFailure("%v", err) + logger.Failuref("%v", err) os.Exit(1) } } diff --git a/cmd/tk/resume_kustomization.go b/cmd/tk/resume_kustomization.go index 05949531..a1d708a8 100644 --- a/cmd/tk/resume_kustomization.go +++ b/cmd/tk/resume_kustomization.go @@ -66,20 +66,20 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error { return err } - logAction("resuming kustomization %s in %s namespace", name, namespace) + logger.Actionf("resuming kustomization %s in %s namespace", name, namespace) kustomization.Spec.Suspend = false if err := kubeClient.Update(ctx, &kustomization); err != nil { return err } - logSuccess("kustomization resumed") + logger.Successf("kustomization resumed") - logWaiting("waiting for kustomization sync") + logger.Waitingf("waiting for kustomization sync") if err := wait.PollImmediate(pollInterval, timeout, isKustomizationResumed(ctx, kubeClient, name, namespace)); err != nil { return err } - logSuccess("kustomization sync completed") + logger.Successf("kustomization sync completed") err = kubeClient.Get(ctx, namespacedName, &kustomization) if err != nil { @@ -87,7 +87,7 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error { } if kustomization.Status.LastAppliedRevision != "" { - logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision) + logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision) } else { return fmt.Errorf("kustomization sync failed") } diff --git a/cmd/tk/suspend_kustomization.go b/cmd/tk/suspend_kustomization.go index 6c8dd41b..d879a44e 100644 --- a/cmd/tk/suspend_kustomization.go +++ b/cmd/tk/suspend_kustomization.go @@ -60,12 +60,12 @@ func suspendKsCmdRun(cmd *cobra.Command, args []string) error { return err } - logAction("suspending kustomization %s in %s namespace", name, namespace) + logger.Actionf("suspending kustomization %s in %s namespace", name, namespace) kustomization.Spec.Suspend = true if err := kubeClient.Update(ctx, &kustomization); err != nil { return err } - logSuccess("kustomization suspended") + logger.Successf("kustomization suspended") return nil } diff --git a/cmd/tk/sync_kustomization.go b/cmd/tk/sync_kustomization.go index 492c88f0..4631bff3 100644 --- a/cmd/tk/sync_kustomization.go +++ b/cmd/tk/sync_kustomization.go @@ -83,7 +83,7 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error { return err } } else { - logAction("annotating kustomization %s in %s namespace", name, namespace) + logger.Actionf("annotating kustomization %s in %s namespace", name, namespace) if kustomization.Annotations == nil { kustomization.Annotations = map[string]string{ kustomizev1.SyncAtAnnotation: time.Now().String(), @@ -94,16 +94,16 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error { if err := kubeClient.Update(ctx, &kustomization); err != nil { return err } - logSuccess("kustomization annotated") + logger.Successf("kustomization annotated") } - logWaiting("waiting for kustomization sync") + logger.Waitingf("waiting for kustomization sync") if err := wait.PollImmediate(pollInterval, timeout, isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil { return err } - logSuccess("kustomization sync completed") + logger.Successf("kustomization sync completed") err = kubeClient.Get(ctx, namespacedName, &kustomization) if err != nil { @@ -111,7 +111,7 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error { } if kustomization.Status.LastAppliedRevision != "" { - logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision) + logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision) } else { return fmt.Errorf("kustomization sync failed") } diff --git a/cmd/tk/sync_source_git.go b/cmd/tk/sync_source_git.go index 610bcf7b..72460bfe 100644 --- a/cmd/tk/sync_source_git.go +++ b/cmd/tk/sync_source_git.go @@ -59,7 +59,7 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error { Name: name, } - logAction("annotating source %s in %s namespace", name, namespace) + logger.Actionf("annotating source %s in %s namespace", name, namespace) var gitRepository sourcev1.GitRepository err = kubeClient.Get(ctx, namespacedName, &gitRepository) if err != nil { @@ -76,15 +76,15 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error { if err := kubeClient.Update(ctx, &gitRepository); err != nil { return err } - logSuccess("source annotated") + logger.Successf("source annotated") - logWaiting("waiting for git sync") + logger.Waitingf("waiting for git sync") if err := wait.PollImmediate(pollInterval, timeout, isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil { return err } - logSuccess("git sync completed") + logger.Successf("git sync completed") err = kubeClient.Get(ctx, namespacedName, &gitRepository) if err != nil { @@ -92,7 +92,7 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if gitRepository.Status.Artifact != nil { - logSuccess("fetched revision: %s", gitRepository.Status.Artifact.Revision) + logger.Successf("fetched revision %s", gitRepository.Status.Artifact.Revision) } else { return fmt.Errorf("git sync failed, artifact not found") } diff --git a/cmd/tk/uninstall.go b/cmd/tk/uninstall.go index 26f8e145..7e145c73 100644 --- a/cmd/tk/uninstall.go +++ b/cmd/tk/uninstall.go @@ -76,7 +76,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { } if uninstallKustomizations { - logAction("uninstalling kustomizations") + logger.Actionf("uninstalling kustomizations") command := fmt.Sprintf("kubectl -n %s delete kustomizations --all --timeout=%s %s", namespace, timeout.String(), dryRun) if _, err := utils.execCommand(ctx, ModeOS, command); err != nil { @@ -85,7 +85,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { // TODO: use the kustomizations snapshots to create a list of objects // that are subject to deletion and wait for all of them to be terminated - logWaiting("waiting on GC") + logger.Waitingf("waiting on GC") time.Sleep(30 * time.Second) } @@ -94,13 +94,13 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { kinds += ",crds" } - logAction("uninstalling components") + logger.Actionf("uninstalling components") command := fmt.Sprintf("kubectl delete %s -l app.kubernetes.io/instance=%s --timeout=%s %s", kinds, namespace, timeout.String(), dryRun) if _, err := utils.execCommand(ctx, ModeOS, command); err != nil { return fmt.Errorf("uninstall failed") } - logSuccess("uninstall finished") + logger.Successf("uninstall finished") return nil } diff --git a/pkg/log/log.go b/pkg/log/log.go new file mode 100644 index 00000000..ad87bb96 --- /dev/null +++ b/pkg/log/log.go @@ -0,0 +1,29 @@ +/* +Copyright 2020 The Flux CD contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package log + +type Logger interface { + // Actionf logs a formatted action message. + Actionf(format string, a ...interface{}) + // Generatef logs a formatted generate message. + Generatef(format string, a ...interface{}) + // Waitingf logs a formatted waiting message. + Waitingf(format string, a ...interface{}) + // Waitingf logs a formatted success message. + Successf(format string, a ...interface{}) + // Failuref logs a formatted failure message. + Failuref(format string, a ...interface{}) +}