github.com/splunk/dan1-qbec@v0.7.3/internal/commands/env.go (about)

     1  /*
     2     Copyright 2019 Splunk Inc.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package commands
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"sort"
    23  	"strings"
    24  
    25  	"github.com/ghodss/yaml"
    26  	"github.com/spf13/cobra"
    27  )
    28  
    29  func newEnvCommand(cp ConfigProvider) *cobra.Command {
    30  	cmd := &cobra.Command{
    31  		Use:   "env <subcommand>",
    32  		Short: "environment lists and details",
    33  	}
    34  	cmd.AddCommand(newEnvListCommand(cp), newEnvVarsCommand(cp))
    35  	return cmd
    36  }
    37  
    38  type envListCommandConfig struct {
    39  	*Config
    40  	format string
    41  }
    42  
    43  func newEnvListCommand(cp ConfigProvider) *cobra.Command {
    44  	cmd := &cobra.Command{
    45  		Use:     "list [-o <format>]",
    46  		Short:   "list all environments in short, json or yaml format",
    47  		Example: envListExamples(),
    48  	}
    49  
    50  	config := envListCommandConfig{}
    51  	cmd.Flags().StringVarP(&config.format, "format", "o", "", "use json|yaml to display machine readable output")
    52  
    53  	cmd.RunE = func(c *cobra.Command, args []string) error {
    54  		config.Config = cp()
    55  		return wrapError(doEnvList(args, config))
    56  	}
    57  	return cmd
    58  }
    59  
    60  type displayEnv struct {
    61  	Name             string `json:"name"`
    62  	Server           string `json:"server"`
    63  	DefaultNamespace string `json:"defaultNamespace"`
    64  }
    65  
    66  type displayEnvList struct {
    67  	Environments []displayEnv `json:"environments"`
    68  }
    69  
    70  func listEnvironments(config envListCommandConfig) error {
    71  	app := config.Config.App()
    72  	var list []displayEnv
    73  	for name, obj := range app.Environments() {
    74  		defNs := obj.DefaultNamespace
    75  		if defNs == "" {
    76  			defNs = "default"
    77  		}
    78  		list = append(list, displayEnv{
    79  			Name:             name,
    80  			Server:           obj.Server,
    81  			DefaultNamespace: defNs,
    82  		})
    83  	}
    84  	sort.Slice(list, func(i, j int) bool {
    85  		return list[i].Name < list[j].Name
    86  	})
    87  
    88  	wrapper := displayEnvList{list}
    89  	w := config.Stdout()
    90  
    91  	switch config.format {
    92  	case "json":
    93  		enc := json.NewEncoder(w)
    94  		enc.SetIndent("", "  ")
    95  		_ = enc.Encode(wrapper)
    96  	case "yaml":
    97  		b, _ := yaml.Marshal(wrapper)
    98  		_, _ = w.Write(b)
    99  	case "":
   100  		for _, e := range list {
   101  			fmt.Fprintln(w, e.Name)
   102  		}
   103  	default:
   104  		return newUsageError(fmt.Sprintf("listEnvironments: unsupported format %q", config.format))
   105  	}
   106  	return nil
   107  }
   108  
   109  func doEnvList(args []string, config envListCommandConfig) error {
   110  	if len(args) != 0 {
   111  		return newUsageError("extra arguments specified")
   112  	}
   113  	return listEnvironments(config)
   114  }
   115  
   116  func newEnvVarsCommand(cp ConfigProvider) *cobra.Command {
   117  	cmd := &cobra.Command{
   118  		Use:     "vars [-o <format>] <env>",
   119  		Short:   "print variables for kubeconfig, context and cluster for an environment",
   120  		Example: envVarsExamples(),
   121  	}
   122  
   123  	config := envVarsCommandConfig{}
   124  	cmd.Flags().StringVarP(&config.format, "format", "o", "", "use json|yaml to display machine readable output")
   125  
   126  	cmd.RunE = func(c *cobra.Command, args []string) error {
   127  		config.Config = cp()
   128  		return wrapError(doEnvVars(args, config))
   129  	}
   130  	return cmd
   131  }
   132  
   133  type envVarsCommandConfig struct {
   134  	*Config
   135  	format string
   136  }
   137  
   138  func doEnvVars(args []string, config envVarsCommandConfig) error {
   139  	if len(args) != 1 {
   140  		return newUsageError("exactly one environment required")
   141  	}
   142  	if _, ok := config.app.Environments()[args[0]]; !ok {
   143  		return fmt.Errorf("invalid environment: %q", args[0])
   144  	}
   145  	return environmentVars(args[0], config)
   146  }
   147  
   148  func environmentVars(name string, config envVarsCommandConfig) error {
   149  	attrs, err := config.KubeAttributes(name)
   150  	if err != nil {
   151  		return err
   152  	}
   153  	w := config.Stdout()
   154  	switch config.format {
   155  	case "json":
   156  		enc := json.NewEncoder(w)
   157  		enc.SetIndent("", "  ")
   158  		_ = enc.Encode(attrs)
   159  	case "yaml":
   160  		b, _ := yaml.Marshal(attrs)
   161  		_, _ = w.Write(b)
   162  	case "":
   163  		var kcArgs []string
   164  		addArg := func(name, value string) {
   165  			if value != "" {
   166  				kcArgs = append(kcArgs, fmt.Sprintf(`--%s=%s`, name, value))
   167  			}
   168  		}
   169  		addArg("context", attrs.Context)
   170  		addArg("cluster", attrs.Cluster)
   171  		addArg("namespace", attrs.Namespace)
   172  
   173  		var lines []string
   174  		var vars []string
   175  		addLine := func(name, value string) {
   176  			lines = append(lines, fmt.Sprintf(`%s='%s'`, name, value))
   177  			vars = append(vars, name)
   178  		}
   179  		addLine("KUBECONFIG", attrs.ConfigFile)
   180  		addLine("KUBE_CLUSTER", attrs.Cluster)
   181  		addLine("KUBE_CONTEXT", attrs.Context)
   182  		addLine("KUBE_NAMESPACE", attrs.Namespace)
   183  		addLine("KUBECTL_ARGS", strings.Join(kcArgs, " "))
   184  
   185  		for _, l := range lines {
   186  			fmt.Fprintf(w, "%s;\n", l)
   187  		}
   188  		fmt.Fprintf(w, "export %s\n", strings.Join(vars, " "))
   189  	default:
   190  		return newUsageError(fmt.Sprintf("environmentVars: unsupported format %q", config.format))
   191  	}
   192  	return nil
   193  }