From 14baaca3a38579acadf2ece746072e34651e8b03 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 13 Sep 2021 11:34:52 +0000 Subject: [PATCH 1/8] feat: humanwriter: prefix with result.Name if present --- internal/humanwriter/human.go | 7 ++++++- internal/humanwriter/human_test.go | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/humanwriter/human.go b/internal/humanwriter/human.go index 67ed422..85ef805 100644 --- a/internal/humanwriter/human.go +++ b/internal/humanwriter/human.go @@ -82,6 +82,11 @@ func (w *HumanResultWriter) WriteResult(result *api.CheckResult) error { return err } - _, err = fmt.Fprintln(w.out, prefix, result.Summary) + namePrefix := "" + if result.Name != "" { + namePrefix = fmt.Sprintf(" [%s]", result.Name) + } + + _, err = fmt.Fprintf(w.out, "%s%s %s\n", prefix, namePrefix, result.Summary) return err } diff --git a/internal/humanwriter/human_test.go b/internal/humanwriter/human_test.go index cb15bf2..6514878 100644 --- a/internal/humanwriter/human_test.go +++ b/internal/humanwriter/human_test.go @@ -52,13 +52,13 @@ func TestHumanWriter(t *testing.T) { var expected string switch mode { case humanwriter.OutputModeEmoji: - expected = "👍 human writer check test\n" + + expected = "👍 [check-test] human writer check test\n" + "🔔 summary\n" + "👎 failed message\n" + "⚠️ \n" + "⏩ skipped check\n" case humanwriter.OutputModeText: - expected = "PASS human writer check test\n" + + expected = "PASS [check-test] human writer check test\n" + "INFO summary\n" + "FAIL failed message\n" + "WARN \n" + From 614ff14db2e930fedbcb98df9d20df423dcaad1e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 13 Sep 2021 11:35:31 +0000 Subject: [PATCH 2/8] fix: internal/checks/kube: remove duplicated resource names in output --- internal/checks/kube/rbac.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/internal/checks/kube/rbac.go b/internal/checks/kube/rbac.go index f7c09a7..f34c030 100644 --- a/internal/checks/kube/rbac.go +++ b/internal/checks/kube/rbac.go @@ -159,29 +159,27 @@ func (k *KubernetesChecker) checkRBACFallback(ctx context.Context) []*api.CheckR results := make([]*api.CheckResult, 0) for req, reqVerbs := range k.reqs.ResourceRequirements { - resName := fmt.Sprintf("%s-%s", checkName, req.Resource) if err := k.checkOneRBACSSAR(ctx, authClient, req, reqVerbs); err != nil { summary := fmt.Sprintf("missing permissions on resource %s: %s", req.Resource, err) - results = append(results, api.ErrorResult(resName, summary, err)) + results = append(results, api.ErrorResult(checkName, summary, err)) continue } summary := fmt.Sprintf("%s: can %s", req.Resource, strings.Join(reqVerbs, ", ")) - results = append(results, api.PassResult(resName, summary)) + results = append(results, api.PassResult(checkName, summary)) } // TODO: delete this when the enterprise-helm role no longer requests resources on things // that don't exist. for req, reqVerbs := range k.reqs.RoleOnlyResourceRequirements { - resName := fmt.Sprintf("%s-%s", checkName, req.Resource) if err := k.checkOneRBACSSAR(ctx, authClient, req, reqVerbs); err != nil { summary := fmt.Sprintf("missing permissions on resource %s: %s", req.Resource, err) - results = append(results, api.ErrorResult(resName, summary, err)) + results = append(results, api.ErrorResult(checkName, summary, err)) continue } summary := fmt.Sprintf("%s: can %s", req.Resource, strings.Join(reqVerbs, ", ")) - results = append(results, api.PassResult(resName, summary)) + results = append(results, api.PassResult(checkName, summary)) } return results From 7df3d0ccc7bfac671a1ce98d449743a20b0ec41a Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 13 Sep 2021 11:38:40 +0000 Subject: [PATCH 3/8] feat: enable pretty output --- internal/cmd/check/check.go | 1 + internal/cmd/check/kubernetes/kubernetes.go | 31 ++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/internal/cmd/check/check.go b/internal/cmd/check/check.go index 9532abd..1a9b0b3 100644 --- a/internal/cmd/check/check.go +++ b/internal/cmd/check/check.go @@ -15,6 +15,7 @@ func NewCommand() *cobra.Command { checkCmd.PersistentFlags().Int("verbosity", 0, "log level verbosity") checkCmd.PersistentFlags().String("coder-version", "1.21", "version of Coder") + checkCmd.PersistentFlags().Bool("no-color", false, "disable colorful output") checkCmd.AddCommand( kubernetes.NewCommand(), diff --git a/internal/cmd/check/kubernetes/kubernetes.go b/internal/cmd/check/kubernetes/kubernetes.go index 24a5e9e..51d79b1 100644 --- a/internal/cmd/check/kubernetes/kubernetes.go +++ b/internal/cmd/check/kubernetes/kubernetes.go @@ -120,15 +120,20 @@ func run(cmd *cobra.Command, _ []string) error { currentContext.Namespace = "default" } - log.Info(cmd.Context(), "kubernetes config:", - slog.F("context", rawConfig.CurrentContext), - slog.F("cluster", currentContext.Cluster), - slog.F("namespace", currentContext.Namespace), - slog.F("authinfo", currentContext.AuthInfo), + noColorFlag, err := cmd.Flags().GetBool("no-color") + if err != nil { + return xerrors.Errorf("parse no-color: %w", err) + } + outputMode := humanwriter.OutputModeEmoji + if noColorFlag { + outputMode = humanwriter.OutputModeText + } + hw := humanwriter.New( + os.Stdout, + humanwriter.WithColors(!noColorFlag), + humanwriter.WithMode(outputMode), ) - hw := humanwriter.New(os.Stdout) - localChecker := local.NewChecker( local.WithLogger(log), local.WithCoderVersion(cv), @@ -144,6 +149,18 @@ func run(cmd *cobra.Command, _ []string) error { kube.WithNamespace(currentContext.Namespace), ) + _ = hw.WriteResult(&api.CheckResult{ + Name: "kubernetes config", + State: api.StateInfo, + Summary: "using the following context to talk to kubernetes", + Details: map[string]interface{}{ + "context": rawConfig.CurrentContext, + "cluster": currentContext.Cluster, + "namespace": currentContext.Namespace, + "authinfo": currentContext.AuthInfo, + }, + }) + if err := localChecker.Validate(); err != nil { return xerrors.Errorf("failed to validate local checks: %w", err) } From 62786bd019c8048aa9caa98cfecbf9dda1537ce7 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 13 Sep 2021 12:01:35 +0000 Subject: [PATCH 4/8] fix: humanwriter does not print result.Details (and probably should not?) --- internal/cmd/check/kubernetes/kubernetes.go | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/internal/cmd/check/kubernetes/kubernetes.go b/internal/cmd/check/kubernetes/kubernetes.go index 51d79b1..eb64982 100644 --- a/internal/cmd/check/kubernetes/kubernetes.go +++ b/internal/cmd/check/kubernetes/kubernetes.go @@ -150,15 +150,27 @@ func run(cmd *cobra.Command, _ []string) error { ) _ = hw.WriteResult(&api.CheckResult{ - Name: "kubernetes config", + Name: "kubernetes current-context", State: api.StateInfo, - Summary: "using the following context to talk to kubernetes", - Details: map[string]interface{}{ - "context": rawConfig.CurrentContext, - "cluster": currentContext.Cluster, - "namespace": currentContext.Namespace, - "authinfo": currentContext.AuthInfo, - }, + Summary: rawConfig.CurrentContext, + }) + + _ = hw.WriteResult(&api.CheckResult{ + Name: "kubernetes cluster", + State: api.StateInfo, + Summary: currentContext.Cluster, + }) + + _ = hw.WriteResult(&api.CheckResult{ + Name: "kubernetes namespace", + State: api.StateInfo, + Summary: currentContext.Namespace, + }) + + _ = hw.WriteResult(&api.CheckResult{ + Name: "kubernetes authinfo", + State: api.StateInfo, + Summary: currentContext.AuthInfo, }) if err := localChecker.Validate(); err != nil { From 28d7032bc41d8a8d5757bdec37615ecc7055ab38 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 14 Sep 2021 09:35:43 +0000 Subject: [PATCH 5/8] feat: separate color and ascii arguments, attach to rootCmd --- internal/cmd/check/check.go | 1 - internal/cmd/check/kubernetes/kubernetes.go | 29 +++++++++++++-------- internal/cmd/root.go | 3 +++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/internal/cmd/check/check.go b/internal/cmd/check/check.go index 1a9b0b3..9532abd 100644 --- a/internal/cmd/check/check.go +++ b/internal/cmd/check/check.go @@ -15,7 +15,6 @@ func NewCommand() *cobra.Command { checkCmd.PersistentFlags().Int("verbosity", 0, "log level verbosity") checkCmd.PersistentFlags().String("coder-version", "1.21", "version of Coder") - checkCmd.PersistentFlags().Bool("no-color", false, "disable colorful output") checkCmd.AddCommand( kubernetes.NewCommand(), diff --git a/internal/cmd/check/kubernetes/kubernetes.go b/internal/cmd/check/kubernetes/kubernetes.go index eb64982..e36b28d 100644 --- a/internal/cmd/check/kubernetes/kubernetes.go +++ b/internal/cmd/check/kubernetes/kubernetes.go @@ -120,24 +120,31 @@ func run(cmd *cobra.Command, _ []string) error { currentContext.Namespace = "default" } - noColorFlag, err := cmd.Flags().GetBool("no-color") + colorFlag, err := cmd.Flags().GetBool("color") if err != nil { - return xerrors.Errorf("parse no-color: %w", err) + return xerrors.Errorf("parse color: %w", err) } + + asciiFlag, err := cmd.Flags().GetBool("ascii") + if err != nil { + return xerrors.Errorf("parse ascii: %w", err) + } + outputMode := humanwriter.OutputModeEmoji - if noColorFlag { + if asciiFlag { outputMode = humanwriter.OutputModeText } - hw := humanwriter.New( + + var writer api.ResultWriter = humanwriter.New( os.Stdout, - humanwriter.WithColors(!noColorFlag), + humanwriter.WithColors(colorFlag), humanwriter.WithMode(outputMode), ) localChecker := local.NewChecker( local.WithLogger(log), local.WithCoderVersion(cv), - local.WithWriter(hw), + local.WithWriter(writer), local.WithTarget(api.CheckTargetKubernetes), ) @@ -145,29 +152,29 @@ func run(cmd *cobra.Command, _ []string) error { clientset, kube.WithLogger(log), kube.WithCoderVersion(cv), - kube.WithWriter(hw), + kube.WithWriter(writer), kube.WithNamespace(currentContext.Namespace), ) - _ = hw.WriteResult(&api.CheckResult{ + _ = writer.WriteResult(&api.CheckResult{ Name: "kubernetes current-context", State: api.StateInfo, Summary: rawConfig.CurrentContext, }) - _ = hw.WriteResult(&api.CheckResult{ + _ = writer.WriteResult(&api.CheckResult{ Name: "kubernetes cluster", State: api.StateInfo, Summary: currentContext.Cluster, }) - _ = hw.WriteResult(&api.CheckResult{ + _ = writer.WriteResult(&api.CheckResult{ Name: "kubernetes namespace", State: api.StateInfo, Summary: currentContext.Namespace, }) - _ = hw.WriteResult(&api.CheckResult{ + _ = writer.WriteResult(&api.CheckResult{ Name: "kubernetes authinfo", State: api.StateInfo, Summary: currentContext.AuthInfo, diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 13d2af4..bfef71c 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -19,5 +19,8 @@ func NewDefaultDoctorCommand() *cobra.Command { check.NewCommand(), ) + rootCmd.PersistentFlags().Bool("color", true, "enable colorful output") + rootCmd.PersistentFlags().Bool("ascii", false, "output ascii only") + return rootCmd } From f4a51bfdb38c521300054b5f7a27dc2d01f8c47b Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 14 Sep 2021 09:41:01 +0000 Subject: [PATCH 6/8] revert: revert adding result.Name prefix to HumanWriter --- internal/humanwriter/human.go | 7 +------ internal/humanwriter/human_test.go | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/internal/humanwriter/human.go b/internal/humanwriter/human.go index 85ef805..85f24fd 100644 --- a/internal/humanwriter/human.go +++ b/internal/humanwriter/human.go @@ -82,11 +82,6 @@ func (w *HumanResultWriter) WriteResult(result *api.CheckResult) error { return err } - namePrefix := "" - if result.Name != "" { - namePrefix = fmt.Sprintf(" [%s]", result.Name) - } - - _, err = fmt.Fprintf(w.out, "%s%s %s\n", prefix, namePrefix, result.Summary) + _, err = fmt.Fprintf(w.out, "%s %s\n", prefix, result.Summary) return err } diff --git a/internal/humanwriter/human_test.go b/internal/humanwriter/human_test.go index 6514878..cb15bf2 100644 --- a/internal/humanwriter/human_test.go +++ b/internal/humanwriter/human_test.go @@ -52,13 +52,13 @@ func TestHumanWriter(t *testing.T) { var expected string switch mode { case humanwriter.OutputModeEmoji: - expected = "👍 [check-test] human writer check test\n" + + expected = "👍 human writer check test\n" + "🔔 summary\n" + "👎 failed message\n" + "⚠️ \n" + "⏩ skipped check\n" case humanwriter.OutputModeText: - expected = "PASS [check-test] human writer check test\n" + + expected = "PASS human writer check test\n" + "INFO summary\n" + "FAIL failed message\n" + "WARN \n" + From 82cec105e5a817b1e55dfe75e063277c53910455 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 14 Sep 2021 09:41:47 +0000 Subject: [PATCH 7/8] consolidate kube auth info into one simple monthly payment --- internal/cmd/check/kubernetes/kubernetes.go | 27 ++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/internal/cmd/check/kubernetes/kubernetes.go b/internal/cmd/check/kubernetes/kubernetes.go index e36b28d..08a3a45 100644 --- a/internal/cmd/check/kubernetes/kubernetes.go +++ b/internal/cmd/check/kubernetes/kubernetes.go @@ -1,6 +1,7 @@ package kubernetes import ( + "fmt" "os" "github.com/Masterminds/semver/v3" @@ -159,25 +160,13 @@ func run(cmd *cobra.Command, _ []string) error { _ = writer.WriteResult(&api.CheckResult{ Name: "kubernetes current-context", State: api.StateInfo, - Summary: rawConfig.CurrentContext, - }) - - _ = writer.WriteResult(&api.CheckResult{ - Name: "kubernetes cluster", - State: api.StateInfo, - Summary: currentContext.Cluster, - }) - - _ = writer.WriteResult(&api.CheckResult{ - Name: "kubernetes namespace", - State: api.StateInfo, - Summary: currentContext.Namespace, - }) - - _ = writer.WriteResult(&api.CheckResult{ - Name: "kubernetes authinfo", - State: api.StateInfo, - Summary: currentContext.AuthInfo, + Summary: fmt.Sprintf("kube context: %q", rawConfig.CurrentContext), + Details: map[string]interface{}{ + "current-context": rawConfig.CurrentContext, + "cluster": currentContext.Cluster, + "namespace": currentContext.Namespace, + "user": currentContext.AuthInfo, + }, }) if err := localChecker.Validate(); err != nil { From 205a1388eca5ffae0a6336378e368a7042ddb258 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 14 Sep 2021 09:50:14 +0000 Subject: [PATCH 8/8] fixup! feat: separate color and ascii arguments, attach to rootCmd --- internal/cmd/check/kubernetes/kubernetes.go | 8 ++++---- internal/cmd/root.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/cmd/check/kubernetes/kubernetes.go b/internal/cmd/check/kubernetes/kubernetes.go index 08a3a45..8c5d527 100644 --- a/internal/cmd/check/kubernetes/kubernetes.go +++ b/internal/cmd/check/kubernetes/kubernetes.go @@ -121,14 +121,14 @@ func run(cmd *cobra.Command, _ []string) error { currentContext.Namespace = "default" } - colorFlag, err := cmd.Flags().GetBool("color") + colorFlag, err := cmd.Flags().GetBool("output-colors") if err != nil { - return xerrors.Errorf("parse color: %w", err) + return xerrors.Errorf("parse output-color: %w", err) } - asciiFlag, err := cmd.Flags().GetBool("ascii") + asciiFlag, err := cmd.Flags().GetBool("output-ascii") if err != nil { - return xerrors.Errorf("parse ascii: %w", err) + return xerrors.Errorf("parse output-ascii: %w", err) } outputMode := humanwriter.OutputModeEmoji diff --git a/internal/cmd/root.go b/internal/cmd/root.go index bfef71c..c9e1f2a 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -19,8 +19,8 @@ func NewDefaultDoctorCommand() *cobra.Command { check.NewCommand(), ) - rootCmd.PersistentFlags().Bool("color", true, "enable colorful output") - rootCmd.PersistentFlags().Bool("ascii", false, "output ascii only") + rootCmd.PersistentFlags().Bool("output-colors", true, "enable colorful output") + rootCmd.PersistentFlags().Bool("output-ascii", false, "output ascii only") return rootCmd }