1/* 2Copyright 2018 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package add 18 19import ( 20 "fmt" 21 "strings" 22 23 "sigs.k8s.io/kustomize/pkg/fs" 24) 25 26// flagsAndArgs encapsulates the options for add secret/configmap commands. 27type flagsAndArgs struct { 28 // Name of configMap/Secret (required) 29 Name string 30 // FileSources to derive the configMap/Secret from (optional) 31 FileSources []string 32 // LiteralSources to derive the configMap/Secret from (optional) 33 LiteralSources []string 34 // EnvFileSource to derive the configMap/Secret from (optional) 35 // TODO: Rationalize this name with Generic.EnvSource 36 EnvFileSource string 37 // Type of secret to create 38 Type string 39} 40 41// Validate validates required fields are set to support structured generation. 42func (a *flagsAndArgs) Validate(args []string) error { 43 if len(args) != 1 { 44 return fmt.Errorf("name must be specified once") 45 } 46 a.Name = args[0] 47 if len(a.EnvFileSource) == 0 && len(a.FileSources) == 0 && len(a.LiteralSources) == 0 { 48 return fmt.Errorf("at least from-env-file, or from-file or from-literal must be set") 49 } 50 if len(a.EnvFileSource) > 0 && (len(a.FileSources) > 0 || len(a.LiteralSources) > 0) { 51 return fmt.Errorf("from-env-file cannot be combined with from-file or from-literal") 52 } 53 // TODO: Should we check if the path exists? if it's valid, if it's within the same (sub-)directory? 54 return nil 55} 56 57// ExpandFileSource normalizes a string list, possibly 58// containing globs, into a validated, globless list. 59// For example, this list: 60// some/path 61// some/dir/a* 62// bfile=some/dir/b* 63// becomes: 64// some/path 65// some/dir/airplane 66// some/dir/ant 67// some/dir/apple 68// bfile=some/dir/banana 69// i.e. everything is converted to a key=value pair, 70// where the value is always a relative file path, 71// and the key, if missing, is the same as the value. 72// In the case where the key is explicitly declared, 73// the globbing, if present, must have exactly one match. 74func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { 75 var results []string 76 for _, pattern := range a.FileSources { 77 var patterns []string 78 key := "" 79 // check if the pattern is in `--from-file=[key=]source` format 80 // and if so split it to send only the file-pattern to glob function 81 s := strings.Split(pattern, "=") 82 if len(s) == 2 { 83 patterns = append(patterns, s[1]) 84 key = s[0] 85 } else { 86 patterns = append(patterns, s[0]) 87 } 88 result, err := globPatterns(fSys, patterns) 89 if err != nil { 90 return err 91 } 92 // if the format is `--from-file=[key=]source` accept only one result 93 // and extend it with the `key=` prefix 94 if key != "" { 95 if len(result) != 1 { 96 return fmt.Errorf( 97 "'pattern '%s' catches files %v, should catch only one", pattern, result) 98 } 99 fileSource := fmt.Sprintf("%s=%s", key, result[0]) 100 results = append(results, fileSource) 101 } else { 102 results = append(results, result...) 103 } 104 } 105 a.FileSources = results 106 return nil 107} 108