metroctl: add --columns options for `node describe`

Change-Id: I58763edc25de7ac50885beb343831ae1b65ec65d
Reviewed-on: https://review.monogon.dev/c/monogon/+/3100
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/cli/metroctl/cmd_node.go b/metropolis/cli/metroctl/cmd_node.go
index 0476d99..6273710 100644
--- a/metropolis/cli/metroctl/cmd_node.go
+++ b/metropolis/cli/metroctl/cmd_node.go
@@ -30,7 +30,7 @@
 
 var nodeDescribeCmd = &cobra.Command{
 	Short:   "Describes cluster nodes.",
-	Use:     "describe [node-id] [--filter] [--output] [--format]",
+	Use:     "describe [node-id] [--filter] [--output] [--format] [--columns]",
 	Example: "metroctl node describe metropolis-c556e31c3fa2bf0a36e9ccb9fd5d6056",
 	Run: func(cmd *cobra.Command, args []string) {
 		ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
@@ -42,7 +42,16 @@
 			log.Fatalf("While calling Management.GetNodes: %v", err)
 		}
 
-		printNodes(nodes, args, nil)
+		var columns map[string]bool
+		if flags.columns != "" {
+			columns = make(map[string]bool)
+			for _, p := range strings.Split(flags.columns, ",") {
+				p = strings.ToLower(p)
+				p = strings.TrimSpace(p)
+				columns[p] = true
+			}
+		}
+		printNodes(nodes, args, columns)
 	},
 	Args: cobra.ArbitraryArgs,
 }
diff --git a/metropolis/cli/metroctl/main.go b/metropolis/cli/metroctl/main.go
index e3ae92b..cdc4947 100644
--- a/metropolis/cli/metroctl/main.go
+++ b/metropolis/cli/metroctl/main.go
@@ -41,6 +41,10 @@
 	// certificate of the cluster as the trusted CA certificate for this cluster.
 	// This is unsafe and should only be used for testing.
 	acceptAnyCA bool
+	// columns is a comma-separated list of column names which selects which columns
+	// will be output to the user. An empty string means all columns will be
+	// displayed.
+	columns string
 }
 
 var flags metroctlFlags
@@ -52,6 +56,7 @@
 	rootCmd.PersistentFlags().BoolVar(&flags.verbose, "verbose", false, "Log additional runtime information")
 	rootCmd.PersistentFlags().StringVar(&flags.format, "format", "plaintext", "Data output format")
 	rootCmd.PersistentFlags().StringVar(&flags.filter, "filter", "", "The object filter applied to the output data")
+	rootCmd.PersistentFlags().StringVar(&flags.columns, "columns", "", "Comma-separated list of column names to show. If not set, all columns will be shown")
 	rootCmd.PersistentFlags().StringVarP(&flags.output, "output", "o", "", "Redirects output to the specified file")
 	rootCmd.PersistentFlags().BoolVar(&flags.acceptAnyCA, "insecure-accept-and-persist-first-encountered-ca", false, "Accept the first encountered CA while connecting as the trusted CA for future metroctl connections with this config path. This is very insecure and should only be used for testing.")
 }