github.com/koderover/helm@v2.17.0+incompatible/cmd/helm/inspect.go (about) 1 /* 2 Copyright The Helm Authors. 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 main 18 19 import ( 20 "fmt" 21 "github.com/ghodss/yaml" 22 "github.com/golang/protobuf/ptypes/any" 23 "github.com/spf13/cobra" 24 "io" 25 "strings" 26 27 "k8s.io/helm/pkg/chartutil" 28 ) 29 30 const ( 31 inspectDesc = ` 32 This command inspects a chart and displays information. It takes a chart reference 33 ('stable/drupal'), a full path to a directory or packaged chart, or a URL. 34 35 Inspect prints the contents of the Chart.yaml file and the values.yaml file. 36 ` 37 inspectValuesDesc = ` 38 This command inspects a chart (directory, file, or URL) and displays the contents 39 of the values.yaml file 40 ` 41 inspectChartDesc = ` 42 This command inspects a chart (directory, file, or URL) and displays the contents 43 of the Charts.yaml file 44 ` 45 readmeChartDesc = ` 46 This command inspects a chart (directory, file, or URL) and displays the contents 47 of the README file 48 ` 49 ) 50 51 type inspectCmd struct { 52 chartpath string 53 output string 54 verify bool 55 keyring string 56 out io.Writer 57 version string 58 repoURL string 59 username string 60 password string 61 devel bool 62 63 certFile string 64 keyFile string 65 caFile string 66 } 67 68 const ( 69 chartOnly = "chart" 70 valuesOnly = "values" 71 readmeOnly = "readme" 72 all = "all" 73 ) 74 75 var readmeFileNames = []string{"readme.md", "readme.txt", "readme"} 76 77 func newInspectCmd(out io.Writer) *cobra.Command { 78 insp := &inspectCmd{ 79 out: out, 80 output: all, 81 } 82 83 inspectCommand := &cobra.Command{ 84 Use: "inspect [CHART]", 85 Short: "Inspect a chart", 86 Long: inspectDesc, 87 RunE: func(cmd *cobra.Command, args []string) error { 88 if err := checkArgsLength(len(args), "chart name"); err != nil { 89 return err 90 } 91 if err := insp.prepare(args[0]); err != nil { 92 return err 93 } 94 return insp.run() 95 }, 96 } 97 98 valuesSubCmd := &cobra.Command{ 99 Use: "values [CHART]", 100 Short: "shows inspect values", 101 Long: inspectValuesDesc, 102 RunE: func(cmd *cobra.Command, args []string) error { 103 insp.output = valuesOnly 104 if err := checkArgsLength(len(args), "chart name"); err != nil { 105 return err 106 } 107 if err := insp.prepare(args[0]); err != nil { 108 return err 109 } 110 return insp.run() 111 }, 112 } 113 114 chartSubCmd := &cobra.Command{ 115 Use: "chart [CHART]", 116 Short: "shows inspect chart", 117 Long: inspectChartDesc, 118 RunE: func(cmd *cobra.Command, args []string) error { 119 insp.output = chartOnly 120 if err := checkArgsLength(len(args), "chart name"); err != nil { 121 return err 122 } 123 if err := insp.prepare(args[0]); err != nil { 124 return err 125 } 126 return insp.run() 127 }, 128 } 129 130 readmeSubCmd := &cobra.Command{ 131 Use: "readme [CHART]", 132 Short: "shows inspect readme", 133 Long: readmeChartDesc, 134 RunE: func(cmd *cobra.Command, args []string) error { 135 insp.output = readmeOnly 136 if err := checkArgsLength(len(args), "chart name"); err != nil { 137 return err 138 } 139 if err := insp.prepare(args[0]); err != nil { 140 return err 141 } 142 return insp.run() 143 }, 144 } 145 146 cmds := []*cobra.Command{inspectCommand, readmeSubCmd, valuesSubCmd, chartSubCmd} 147 vflag := "verify" 148 vdesc := "Verify the provenance data for this chart" 149 for _, subCmd := range cmds { 150 subCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) 151 } 152 153 kflag := "keyring" 154 kdesc := "Path to the keyring containing public verification keys" 155 kdefault := defaultKeyring() 156 for _, subCmd := range cmds { 157 subCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) 158 } 159 160 verflag := "version" 161 verdesc := "Version of the chart. By default, the newest chart is shown" 162 for _, subCmd := range cmds { 163 subCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) 164 } 165 166 repoURL := "repo" 167 repoURLdesc := "Chart repository url where to locate the requested chart" 168 for _, subCmd := range cmds { 169 subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) 170 } 171 172 username := "username" 173 usernamedesc := "Chart repository username where to locate the requested chart" 174 inspectCommand.Flags().StringVar(&insp.username, username, "", usernamedesc) 175 valuesSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc) 176 chartSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc) 177 178 password := "password" 179 passworddesc := "Chart repository password where to locate the requested chart" 180 inspectCommand.Flags().StringVar(&insp.password, password, "", passworddesc) 181 valuesSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc) 182 chartSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc) 183 184 develFlag := "devel" 185 develDesc := "Use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored." 186 for _, subCmd := range cmds { 187 subCmd.Flags().BoolVar(&insp.devel, develFlag, false, develDesc) 188 } 189 190 certFile := "cert-file" 191 certFiledesc := "Verify certificates of HTTPS-enabled servers using this CA bundle" 192 for _, subCmd := range cmds { 193 subCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) 194 } 195 196 keyFile := "key-file" 197 keyFiledesc := "Identify HTTPS client using this SSL key file" 198 for _, subCmd := range cmds { 199 subCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) 200 } 201 202 caFile := "ca-file" 203 caFiledesc := "Chart repository url where to locate the requested chart" 204 for _, subCmd := range cmds { 205 subCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) 206 } 207 208 for _, subCmd := range cmds[1:] { 209 inspectCommand.AddCommand(subCmd) 210 } 211 212 return inspectCommand 213 } 214 215 func (i *inspectCmd) prepare(chart string) error { 216 debug("Original chart version: %q", i.version) 217 if i.version == "" && i.devel { 218 debug("setting version to >0.0.0-0") 219 i.version = ">0.0.0-0" 220 } 221 222 cp, err := locateChartPath(i.repoURL, i.username, i.password, chart, i.version, i.verify, i.keyring, 223 i.certFile, i.keyFile, i.caFile) 224 if err != nil { 225 return err 226 } 227 i.chartpath = cp 228 return nil 229 } 230 231 func (i *inspectCmd) run() error { 232 chrt, err := chartutil.Load(i.chartpath) 233 if err != nil { 234 return err 235 } 236 cf, err := yaml.Marshal(chrt.Metadata) 237 if err != nil { 238 return err 239 } 240 241 if i.output == chartOnly || i.output == all { 242 fmt.Fprintln(i.out, string(cf)) 243 } 244 245 if (i.output == valuesOnly || i.output == all) && chrt.Values != nil { 246 if i.output == all { 247 fmt.Fprintln(i.out, "---") 248 } 249 fmt.Fprintln(i.out, chrt.Values.Raw) 250 } 251 252 if i.output == readmeOnly || i.output == all { 253 if i.output == all { 254 fmt.Fprintln(i.out, "---") 255 } 256 readme := findReadme(chrt.Files) 257 if readme == nil { 258 return nil 259 } 260 fmt.Fprintln(i.out, string(readme.Value)) 261 } 262 return nil 263 } 264 265 func findReadme(files []*any.Any) (file *any.Any) { 266 for _, file := range files { 267 if containsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) { 268 return file 269 } 270 } 271 return nil 272 } 273 274 // containsString checks if a given slice of strings contains the provided string. 275 // If a modifier func is provided, it is called with the slice item before the comparison. 276 func containsString(slice []string, s string, modifier func(s string) string) bool { 277 for _, item := range slice { 278 if item == s { 279 return true 280 } 281 if modifier != nil && modifier(item) == s { 282 return true 283 } 284 } 285 return false 286 }