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 }