diff --git a/pkg/commands/configmap.go b/pkg/commands/configmap.go index 2ca97223a..f8065d958 100644 --- a/pkg/commands/configmap.go +++ b/pkg/commands/configmap.go @@ -103,7 +103,7 @@ func addConfigMap(k *types.Kustomization, flagsAndArgs cMapFlagsAndArgs, fSys fs return err } - factory := configmapandsecret.NewConfigMapFactory(cmArgs, fSys) + factory := configmapandsecret.NewConfigMapFactory(cmArgs, fSys, nil) // Validate by trying to create corev1.configmap. _, _, err = factory.MakeUnstructAndGenerateName() diff --git a/pkg/configmapandsecret/configmapfactory.go b/pkg/configmapandsecret/configmapfactory.go index 0fbff0787..5ecbc60f4 100644 --- a/pkg/configmapandsecret/configmapfactory.go +++ b/pkg/configmapandsecret/configmapfactory.go @@ -27,6 +27,7 @@ import ( "github.com/kubernetes-sigs/kustomize/pkg/fs" "github.com/kubernetes-sigs/kustomize/pkg/hash" + "github.com/kubernetes-sigs/kustomize/pkg/loader" "github.com/kubernetes-sigs/kustomize/pkg/types" "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" @@ -39,16 +40,20 @@ import ( type ConfigMapFactory struct { args *types.ConfigMapArgs fSys fs.FileSystem + ldr loader.Loader } // NewConfigMapFactory returns a new ConfigMapFactory. -func NewConfigMapFactory(args *types.ConfigMapArgs, fSys fs.FileSystem) *ConfigMapFactory { - return &ConfigMapFactory{args: args, fSys: fSys} +func NewConfigMapFactory( + args *types.ConfigMapArgs, + fSys fs.FileSystem, + l loader.Loader) *ConfigMapFactory { + return &ConfigMapFactory{args: args, fSys: fSys, ldr: l} } // MakeUnstructAndGenerateName returns an configmap and the name appended with a hash. func (f *ConfigMapFactory) MakeUnstructAndGenerateName() (*unstructured.Unstructured, string, error) { - cm, err := f.MakeConfigMap() + cm, err := f.MakeConfigMap1() if err != nil { return nil, "", err } @@ -71,13 +76,18 @@ func objectToUnstructured(in runtime.Object) (*unstructured.Unstructured, error) return &out, err } -// MakeConfigMap returns a new ConfigMap, or nil and an error. -func (f *ConfigMapFactory) MakeConfigMap() (*corev1.ConfigMap, error) { +func (f *ConfigMapFactory) makeFreshConfigMap() *corev1.ConfigMap { cm := &corev1.ConfigMap{} cm.APIVersion = "v1" cm.Kind = "ConfigMap" cm.Name = f.args.Name cm.Data = map[string]string{} + return cm +} + +// MakeConfigMap1 returns a new ConfigMap, or nil and an error. +func (f *ConfigMapFactory) MakeConfigMap1() (*corev1.ConfigMap, error) { + cm := f.makeFreshConfigMap() if f.args.EnvSource != "" { if err := f.handleConfigMapFromEnvFileSource(cm); err != nil { @@ -94,13 +104,66 @@ func (f *ConfigMapFactory) MakeConfigMap() (*corev1.ConfigMap, error) { return nil, err } } - return cm, nil } +// MakeConfigMap2 returns a new ConfigMap, or nil and an error. +// TODO: Get rid of the nearly duplicated code in MakeConfigMap1 vs MakeConfigMap2 +func (f *ConfigMapFactory) MakeConfigMap2() (*corev1.ConfigMap, error) { + var envPairs, literalPairs, filePairs []kvPair + var err error + + cm := f.makeFreshConfigMap() + + if f.args.EnvSource != "" { + envPairs, err = keyValuesFromEnvFile(f.ldr, f.args.EnvSource) + if err != nil { + return nil, fmt.Errorf( + "error reading keys from env source file: %s %v", + f.args.EnvSource, err) + } + } + + literalPairs, err = keyValuesFromLiteralSources(f.args.LiteralSources) + if err != nil { + return nil, fmt.Errorf( + "error reading key values from literal sources: %v", err) + } + + filePairs, err = keyValuesFromFileSources(f.ldr, f.args.FileSources) + if err != nil { + return nil, fmt.Errorf( + "error reading key values from file sources: %v", err) + } + + allPairs := append(append(envPairs, literalPairs...), filePairs...) + + // merge key value pairs from all the sources + for _, kv := range allPairs { + err = addKV(cm.Data, kv) + if err != nil { + return nil, fmt.Errorf("error adding key in configmap: %v", err) + } + } + return cm, nil +} + +func keyValuesFromLiteralSources(sources []string) ([]kvPair, error) { + var kvs []kvPair + for _, s := range sources { + k, v, err := ParseLiteralSource(s) + if err != nil { + return nil, err + } + kvs = append(kvs, kvPair{key: k, value: v}) + } + return kvs, nil +} + // handleConfigMapFromLiteralSources adds the specified literal source // information into the provided configMap. -func (f *ConfigMapFactory) handleConfigMapFromLiteralSources(configMap *v1.ConfigMap) error { +func (f *ConfigMapFactory) handleConfigMapFromLiteralSources( + configMap *v1.ConfigMap) error { for _, literalSource := range f.args.LiteralSources { keyName, value, err := ParseLiteralSource(literalSource) if err != nil { @@ -114,6 +177,22 @@ func (f *ConfigMapFactory) handleConfigMapFromLiteralSources(configMap *v1.Confi return nil } +func keyValuesFromFileSources(ldr loader.Loader, sources []string) ([]kvPair, error) { + var kvs []kvPair + for _, s := range sources { + k, path, err := ParseFileSource(s) + if err != nil { + return nil, err + } + content, err := ldr.Load(path) + if err != nil { + return nil, err + } + kvs = append(kvs, kvPair{key: k, value: string(content)}) + } + return kvs, nil +} + // handleConfigMapFromFileSources adds the specified file source information // into the provided configMap func (f *ConfigMapFactory) handleConfigMapFromFileSources(configMap *v1.ConfigMap) error { @@ -152,6 +231,14 @@ func (f *ConfigMapFactory) handleConfigMapFromFileSources(configMap *v1.ConfigMa return nil } +func keyValuesFromEnvFile(l loader.Loader, path string) ([]kvPair, error) { + content, err := l.Load(path) + if err != nil { + return nil, err + } + return keyValuesFromLines(content) +} + // HandleConfigMapFromEnvFileSource adds the specified env file source information // into the provided configMap func (f *ConfigMapFactory) handleConfigMapFromEnvFileSource(configMap *v1.ConfigMap) error { @@ -161,7 +248,6 @@ func (f *ConfigMapFactory) handleConfigMapFromEnvFileSource(configMap *v1.Config if f.fSys.IsDir(f.args.EnvSource) { return fmt.Errorf("env config file %s cannot be a directory", f.args.EnvSource) } - return addFromEnvFile(f.args.EnvSource, func(key, value string) error { return addKeyFromLiteralToConfigMap(configMap, key, value) }) @@ -232,3 +318,18 @@ func ParseLiteralSource(source string) (keyName, value string, err error) { return items[0], items[1], nil } + +// addKV adds key-value pair to the provided map. +func addKV(m map[string]string, kv kvPair) error { + if errs := validation.IsConfigMapKey(kv.key); len(errs) != 0 { + return fmt.Errorf( + "%q is not a valid key name: %s", + kv.key, strings.Join(errs, ";")) + } + if _, exists := m[kv.key]; exists { + return fmt.Errorf( + "key %s already exists: %v", kv.key, m) + } + m[kv.key] = kv.value + return nil +} diff --git a/pkg/configmapandsecret/configmapfactory_test.go b/pkg/configmapandsecret/configmapfactory_test.go index 31be33359..52d1c8f28 100644 --- a/pkg/configmapandsecret/configmapfactory_test.go +++ b/pkg/configmapandsecret/configmapfactory_test.go @@ -136,8 +136,8 @@ func TestConstructConfigMap(t *testing.T) { for _, tc := range testCases { // TODO: all tests should use a FakeFs fSys := fs.MakeRealFS() - f := NewConfigMapFactory(&tc.input, fSys) - cm, err := f.MakeConfigMap() + f := NewConfigMapFactory(&tc.input, fSys, nil) + cm, err := f.MakeConfigMap1() if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/resmap/kv.go b/pkg/configmapandsecret/kv.go similarity index 97% rename from pkg/resmap/kv.go rename to pkg/configmapandsecret/kv.go index 9663fa5e1..26a31c54c 100644 --- a/pkg/resmap/kv.go +++ b/pkg/configmapandsecret/kv.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resmap +package configmapandsecret import ( "bufio" @@ -28,8 +28,6 @@ import ( "k8s.io/apimachinery/pkg/util/validation" ) -var utf8bom = []byte{0xEF, 0xBB, 0xBF} - // kvPair represents a key value pair. type kvPair struct { key string diff --git a/pkg/resmap/kv_test.go b/pkg/configmapandsecret/kv_test.go similarity index 98% rename from pkg/resmap/kv_test.go rename to pkg/configmapandsecret/kv_test.go index fefa03240..fb56e6fcb 100644 --- a/pkg/resmap/kv_test.go +++ b/pkg/configmapandsecret/kv_test.go @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package resmap +package configmapandsecret import ( "reflect" diff --git a/pkg/resmap/configmap.go b/pkg/resmap/configmap.go index 9f00ac7d9..80bbb940e 100644 --- a/pkg/resmap/configmap.go +++ b/pkg/resmap/configmap.go @@ -17,123 +17,27 @@ limitations under the License. package resmap import ( - "fmt" - "strings" - "github.com/kubernetes-sigs/kustomize/pkg/configmapandsecret" "github.com/kubernetes-sigs/kustomize/pkg/loader" "github.com/kubernetes-sigs/kustomize/pkg/resource" "github.com/kubernetes-sigs/kustomize/pkg/types" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/validation" ) -func newResourceFromConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*resource.Resource, error) { - cm, err := makeConfigMap(l, cmArgs) - if err != nil { - return nil, err - } - if cmArgs.Behavior == "" { - cmArgs.Behavior = "create" - } - return resource.NewResourceWithBehavior(cm, resource.NewGenerationBehavior(cmArgs.Behavior)) -} - -func makeConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*corev1.ConfigMap, error) { - var envPairs, literalPairs, filePairs []kvPair - var err error - - cm := &corev1.ConfigMap{} - cm.APIVersion = "v1" - cm.Kind = "ConfigMap" - cm.Name = cmArgs.Name - cm.Data = map[string]string{} - - if cmArgs.EnvSource != "" { - envPairs, err = keyValuesFromEnvFile(l, cmArgs.EnvSource) - if err != nil { - return nil, fmt.Errorf("error reading keys from env source file: %s %v", cmArgs.EnvSource, err) - } - } - - literalPairs, err = keyValuesFromLiteralSources(cmArgs.LiteralSources) - if err != nil { - return nil, fmt.Errorf("error reading key values from literal sources: %v", err) - } - - filePairs, err = keyValuesFromFileSources(l, cmArgs.FileSources) - if err != nil { - return nil, fmt.Errorf("error reading key values from file sources: %v", err) - } - - allPairs := append(append(envPairs, literalPairs...), filePairs...) - - // merge key value pairs from all the sources - for _, kv := range allPairs { - err = addKV(cm.Data, kv) - if err != nil { - return nil, fmt.Errorf("error adding key in configmap: %v", err) - } - } - - return cm, nil -} - -func keyValuesFromEnvFile(l loader.Loader, path string) ([]kvPair, error) { - content, err := l.Load(path) - if err != nil { - return nil, err - } - return keyValuesFromLines(content) -} - -func keyValuesFromLiteralSources(sources []string) ([]kvPair, error) { - var kvs []kvPair - for _, s := range sources { - // TODO: move ParseLiteralSource in this file - k, v, err := configmapandsecret.ParseLiteralSource(s) - if err != nil { - return nil, err - } - kvs = append(kvs, kvPair{key: k, value: v}) - } - return kvs, nil -} - -func keyValuesFromFileSources(l loader.Loader, sources []string) ([]kvPair, error) { - var kvs []kvPair - - for _, s := range sources { - key, path, err := configmapandsecret.ParseFileSource(s) - if err != nil { - return nil, err - } - fileContent, err := l.Load(path) - if err != nil { - return nil, err - } - kvs = append(kvs, kvPair{key: key, value: string(fileContent)}) - } - return kvs, nil -} - -// addKV adds key-value pair to the provided map. -func addKV(m map[string]string, kv kvPair) error { - if errs := validation.IsConfigMapKey(kv.key); len(errs) != 0 { - return fmt.Errorf("%q is not a valid key name: %s", kv.key, strings.Join(errs, ";")) - } - if _, exists := m[kv.key]; exists { - return fmt.Errorf("key %s already exists: %v", kv.key, m) - } - m[kv.key] = kv.value - return nil -} - // NewResMapFromConfigMapArgs returns a Resource slice given a configmap metadata slice from kustomization file. -func NewResMapFromConfigMapArgs(loader loader.Loader, cmList []types.ConfigMapArgs) (ResMap, error) { +func NewResMapFromConfigMapArgs( + ldr loader.Loader, cmArgsList []types.ConfigMapArgs) (ResMap, error) { var allResources []*resource.Resource - for _, cm := range cmList { - res, err := newResourceFromConfigMap(loader, cm) + for _, cmArgs := range cmArgsList { + if cmArgs.Behavior == "" { + cmArgs.Behavior = "create" + } + f := configmapandsecret.NewConfigMapFactory(&cmArgs, nil, ldr) + cm, err := f.MakeConfigMap2() + if err != nil { + return nil, err + } + res, err := resource.NewResourceWithBehavior( + cm, resource.NewGenerationBehavior(cmArgs.Behavior)) if err != nil { return nil, err }