diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index d96092fc1..3f0a545d5 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -68,26 +68,22 @@ func TestKeyValuesFromPlugins(t *testing.T) { expected []kv.Pair }{ { - description: "Create kv.Pairs from plugin", + description: "Create kv.Pairs from builtin literals plugin", sources: []types.KVSource{ { - PluginType: "testonly", - Name: "testonly", - Args: []string{"FOO", "BAR", "BAZ"}, + PluginType: "builtin", + Name: "literals", + Args: []string{"FOO=bar", "BAR=baz"}, }, }, expected: []kv.Pair{ { - Key: "k_FOO", - Value: "v_FOO", + Key: "FOO", + Value: "bar", }, { - Key: "k_BAR", - Value: "v_BAR", - }, - { - Key: "k_BAZ", - Value: "v_BAZ", + Key: "BAR", + Value: "baz", }, }, }, diff --git a/k8sdeps/kv/plugin/builtin/literals.go b/k8sdeps/kv/plugin/builtin/literals.go new file mode 100644 index 000000000..bb79744f8 --- /dev/null +++ b/k8sdeps/kv/plugin/builtin/literals.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 builtin + +import ( + "fmt" + "strings" + + "sigs.k8s.io/kustomize/k8sdeps/kv" +) + +// Literals takes a list of literals. +// Each literal source should be a key and literal value, +// e.g. `somekey=somevalue` +// It will be similar to kubectl create configmap|secret --from-literal +type Literals struct{} + +// Get implements the interface for kv plugins. +func (p Literals) Get(root string, args []string) ([]kv.Pair, error) { + var kvs []kv.Pair + for _, s := range args { + k, v, err := parseLiteralSource(s) + if err != nil { + return nil, err + } + kvs = append(kvs, kv.Pair{Key: k, Value: v}) + } + return kvs, nil +} + +// parseLiteralSource parses the source key=val pair into its component pieces. +// This functionality is distinguished from strings.SplitN(source, "=", 2) since +// it returns an error in the case of empty keys, values, or a missing equals sign. +func parseLiteralSource(source string) (keyName, value string, err error) { + // leading equal is invalid + if strings.Index(source, "=") == 0 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + // split after the first equal (so values can have the = character) + items := strings.SplitN(source, "=", 2) + if len(items) != 2 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + return items[0], strings.Trim(items[1], "\"'"), nil +} diff --git a/k8sdeps/kv/plugin/testonly.go b/k8sdeps/kv/plugin/builtinplugin.go similarity index 53% rename from k8sdeps/kv/plugin/testonly.go rename to k8sdeps/kv/plugin/builtinplugin.go index ecbc36cc8..67aeb39fb 100644 --- a/k8sdeps/kv/plugin/testonly.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -14,30 +14,32 @@ See the License for the specific language governing permissions and limitations under the License. */ -// testonly is temporary until we have builtin plugins to use in the tests. - package plugin import ( - "sigs.k8s.io/kustomize/k8sdeps/kv" + "fmt" + + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin/builtin" + "sigs.k8s.io/kustomize/pkg/ifc" ) -var _ Factory = &testonlyFactory{} +var _ Factory = &builtinFactory{} -func newTestonlyFactory() *testonlyFactory { - return &testonlyFactory{} +type builtinFactory struct { + plugins map[string]KVSource } -type testonlyFactory struct{} - -func (p testonlyFactory) Get(_ string, args []string) ([]kv.Pair, error) { - var kvs []kv.Pair - for _, arg := range args { - kvs = append(kvs, kv.Pair{Key: "k_" + arg, Value: "v_" + arg}) +func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { + return &builtinFactory{ + plugins: map[string]KVSource{ + "literals": builtin.Literals{}, + }, } - return kvs, nil } -func (p *testonlyFactory) load(_ string) (KVSource, error) { - return p, nil +func (p *builtinFactory) load(name string) (KVSource, error) { + if plug, ok := p.plugins[name]; ok { + return plug, nil + } + return nil, fmt.Errorf("plugin %s not found", name) } diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index bf6c8ae0a..3883922c7 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -33,8 +33,8 @@ func NewRegistry(ldr ifc.Loader) Registry { return Registry{ ldr: ldr, factories: map[string]Factory{ - "go": newGoFactory(), - "testonly": newTestonlyFactory(), + "go": newGoFactory(), + "builtin": newBuiltinFactory(ldr), }, } } diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index 3ba0545d8..c482b6a7d 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -247,11 +247,11 @@ func TestGeneratorPlugins(t *testing.T) { secretGenerator: - name: bob kvSources: - - pluginType: testonly - name: testonly + - pluginType: builtin + name: literals args: - - FRUIT - - VEGETABLE + - FRUIT=apple + - VEGETABLE=carrot `) m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { @@ -260,11 +260,11 @@ secretGenerator: th.assertActualEqualsExpected(m, ` apiVersion: v1 data: - k_FRUIT: dl9GUlVJVA== - k_VEGETABLE: dl9WRUdFVEFCTEU= + FRUIT: YXBwbGU= + VEGETABLE: Y2Fycm90 kind: Secret metadata: - name: bob-cb9mhbh9gg + name: bob-bgtct8h699 type: Opaque `) }