Merge branch 'master' into builtins

This commit is contained in:
Seth Pollack
2019-03-17 17:01:06 -04:00
committed by GitHub
26 changed files with 683 additions and 530 deletions

View File

@@ -1,37 +1,46 @@
# Transformer Configurations
Kustomize computes the resources by applying a series of transformers:
- namespace transformer
- prefix/suffix transformer
- label transformer
- annotation transformer
- name reference transformer
- variable reference transformer
Kustomize creates new resources by applying a series of transformations to an original
set of resources. Kustomize provides the following default transformers:
Each transformer takes a list of resources and modifies certain fields. The modification is based on the transformer's rule.
The fields to update is the transformer's configuration, which is a list of filedspec that can be represented in YAML format.
- namespace
- prefix/suffix
- label
- annotation
- name reference
- variable reference
## fieldSpec
FieldSpec is a type to represent a path to a field in one kind of resources. It has following format
```
A `fieldSpec` list, in a transformer's configuration, determines which resource types and which fields
within those types the transformer can modify.
## FieldSpec
FieldSpec is a type that represents a path to a field in one kind of resource.
```yaml
group: some-group
version: some-version
kind: some-kind
path: path/to/the/field
create: false
```
If `create` is set to true, it indicates the transformer to create the path if it is not found in the resources. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation.
## prefix/suffix transformer
Name prefix suffix transformer adds prefix and suffix to the `metadata/name` field for all resources with following configuration:
```
If `create` is set to `true`, the transformer creates the path to the field in the resource if the path is not already found. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation.
## Prefix/suffix transformer
The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is the default prefix transformer configuration:
```yaml
namePrefix:
- path: metadata/name
```
## label transformer
Label transformer adds labels to `metadata/labels` field for all resources. It also adds labels to `spec/selector` field in all Service and to `spec/selector/matchLabels` field in all Deployment.
```
## Label transformer
The label transformer adds labels to the `metadata/labels` field for all resources. It also adds labels to the `spec/selector` field in all Service resources as well as the `spec/selector/matchLabels` field in all Deployment resources.
```yaml
commonLabels:
- path: metadata/labels
create: true
@@ -44,15 +53,16 @@ commonLabels:
- path: spec/selector/matchLabels
create: true
kind: Deployment
(etc.)
```
## name reference transformer
Name reference transformer's configuration is different from all other transformers. It contains a list of namebackreferences, which represented all the possible fields that a type could be used as a reference in other types of resources. A namebackreference contains a type such as ConfigMap as well as a list of FieldSpecs where ConfigMap is referenced. Here is an example.
```
## Name reference transformer
Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example:
```yaml
kind: ConfigMap
version: v1
FieldSpecs:
fieldSpecs:
- kind: Pod
version: v1
path: spec/volumes/configMap/name
@@ -60,10 +70,11 @@ FieldSpecs:
path: spec/template/spec/volumes/configMap/name
- kind: Job
path: spec/template/spec/volumes/configMap/name
(etc.)
```
Name reference transformer configuration contains a list of such namebackreferences for ConfigMap, Secret, Service, Role, ServiceAccount and so on.
```
Name reference transformer's configuration contains a list of `nameReferences` for resources such as ConfigMap, Secret, Service, Role, and ServiceAccount. Here is an example configuration:
```yaml
nameReference:
- kind: ConfigMap
version: v1
@@ -74,7 +85,7 @@ nameReference:
- path: spec/containers/env/valueFrom/configMapKeyRef/name
version: v1
kind: Pod
(etc.)
# ...
- kind: Secret
version: v1
fieldSpecs:
@@ -84,12 +95,12 @@ nameReference:
- path: spec/containers/env/valueFrom/secretKeyRef/name
version: v1
kind: Pod
(etc.)
```
## customizing transformer configurations
## Customizing transformer configurations
Kustomize has a default set of transformer configurations. You can save the default transformer configurations to a local directory by calling `kustomize config save -d`, and modify and use these configurations. Kustomize also supports adding new transformer configurations to kustomization.yaml. This tutorial shows how to customize those configurations to:
Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to
- [support a CRD type](crd/README.md)
- add extra fields for variable substitution
- add extra fields for name reference

View File

@@ -21,8 +21,7 @@ import (
"fmt"
"unicode/utf8"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/api/core/v1"
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/types"
@@ -40,8 +39,8 @@ func NewFactory(
}
func makeFreshConfigMap(
args *types.ConfigMapArgs) *corev1.ConfigMap {
cm := &corev1.ConfigMap{}
args *types.ConfigMapArgs) *v1.ConfigMap {
cm := &v1.ConfigMap{}
cm.APIVersion = "v1"
cm.Kind = "ConfigMap"
cm.Name = args.Name
@@ -52,7 +51,7 @@ func makeFreshConfigMap(
// MakeConfigMap returns a new ConfigMap, or nil and an error.
func (f *Factory) MakeConfigMap(
args *types.ConfigMapArgs) (*corev1.ConfigMap, error) {
args *types.ConfigMapArgs) (*v1.ConfigMap, error) {
all, err := f.loadKvPairs(args.GeneratorArgs)
if err != nil {
return nil, err

View File

@@ -1,34 +0,0 @@
/*
Copyright 2018 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 k8sdeps provides kustomize factory with k8s dependencies
package k8sdeps
import (
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/k8sdeps/transformer"
"sigs.k8s.io/kustomize/k8sdeps/validator"
"sigs.k8s.io/kustomize/pkg/factory"
)
// NewFactory creates an instance of KustFactory using k8sdeps factories
func NewFactory() *factory.KustFactory {
return factory.NewKustFactory(
kunstruct.NewKunstructuredFactoryImpl(),
validator.NewKustValidator(),
transformer.NewFactoryImpl(),
)
}

View File

@@ -32,13 +32,21 @@ import (
// KunstructuredFactoryImpl hides construction using apimachinery types.
type KunstructuredFactoryImpl struct {
generatorMetaArgs *types.GeneratorMetaArgs
}
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
// NewKunstructuredFactoryImpl returns a factory.
func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory {
return &KunstructuredFactoryImpl{}
return NewKunstructuredFactoryWithGeneratorArgs(
&types.GeneratorMetaArgs{})
}
// NewKunstructuredFactoryWithGeneratorArgs returns a factory.
func NewKunstructuredFactoryWithGeneratorArgs(
gma *types.GeneratorMetaArgs) ifc.KunstructuredFactory {
return &KunstructuredFactoryImpl{gma}
}
// SliceFromBytes returns a slice of Kunstructured.
@@ -82,7 +90,10 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap(
ldr ifc.Loader,
options *types.GeneratorOptions,
args *types.ConfigMapArgs) (ifc.Kunstructured, error) {
o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeConfigMap(args)
o, err := configmapandsecret.NewFactory(
ldr, options,
plugin.NewConfiguredRegistry(
ldr, &kf.generatorMetaArgs.PluginConfig)).MakeConfigMap(args)
if err != nil {
return nil, err
}
@@ -94,7 +105,10 @@ func (kf *KunstructuredFactoryImpl) MakeSecret(
ldr ifc.Loader,
options *types.GeneratorOptions,
args *types.SecretArgs) (ifc.Kunstructured, error) {
o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeSecret(args)
o, err := configmapandsecret.NewFactory(
ldr, options,
plugin.NewConfiguredRegistry(
ldr, &kf.generatorMetaArgs.PluginConfig)).MakeSecret(args)
if err != nil {
return nil, err
}

View File

@@ -18,23 +18,45 @@ package plugin
import (
"fmt"
"os"
"path/filepath"
"plugin"
"sigs.k8s.io/kustomize/pkg/types"
)
var _ Factory = &goFactory{}
const (
dir = "$HOME/.config/kustomize/plugins/kvsource"
kvSourcesDir = "kvSources"
EnableGoPluginsFlagName = "enable_alpha_goplugins_accept_panic_risk"
EnableGoPluginsFlagHelp = `
Warning: the main program may panic and exit on an
attempt to use a goplugin that was compiled under
conditions differing from the those in effect when
main was compiled. It's safest to use this flag in
the context of a container image holding both the
main and the goplugins it needs, all built on the
same machine, with the same transitive libs and
the same compiler version.
`
errorFmt = `
enable go plugins by specifying flag
--%s
Place .so files in
%s
%s
`
)
func newGoFactory() *goFactory {
func newGoFactory(c *types.PluginConfig) *goFactory {
return &goFactory{
config: c,
plugins: make(map[string]KVSource),
}
}
type goFactory struct {
config *types.PluginConfig
plugins map[string]KVSource
}
@@ -43,7 +65,19 @@ func (p *goFactory) load(name string) (KVSource, error) {
return plug, nil
}
goPlugin, err := plugin.Open(fmt.Sprintf("%s/kustomize-%s.so", os.ExpandEnv(dir), name))
dir := filepath.Join(
p.config.DirectoryPath,
kvSourcesDir)
if !p.config.GoEnabled {
return nil, fmt.Errorf(
errorFmt,
EnableGoPluginsFlagName,
dir,
EnableGoPluginsFlagHelp)
}
goPlugin, err := plugin.Open(
filepath.Join(dir, name+".so"))
if err != nil {
return nil, err
}

View File

@@ -18,8 +18,10 @@ package plugin
import (
"fmt"
"path/filepath"
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/types"
)
// Registry holds all the plugin factories.
@@ -28,17 +30,36 @@ type Registry struct {
ldr ifc.Loader
}
// NewRegistry returns a new Registry loaded with all the factories.
func NewRegistry(ldr ifc.Loader) Registry {
const (
PluginsDir = "plugins"
)
func DefaultPluginConfig() types.PluginConfig {
return types.PluginConfig{
GoEnabled: false,
DirectoryPath: filepath.Join(
pgmconfig.ConfigRoot(), PluginsDir),
}
}
// NewConfiguredRegistry returns a new Registry loaded
// with all the factories and a custom PluginConfig.
func NewConfiguredRegistry(
ldr ifc.Loader, pc *types.PluginConfig) Registry {
return Registry{
ldr: ldr,
factories: map[string]Factory{
"go": newGoFactory(),
"go": newGoFactory(pc),
"builtin": newBuiltinFactory(ldr),
},
}
}
// NewRegistry returns a new Registry with default config.
func NewRegistry(ldr ifc.Loader) Registry {
return NewConfiguredRegistry(ldr, &types.PluginConfig{})
}
// Load returns a plugin by type and name,
func (r *Registry) Load(pluginType, name string) (KVSource, error) {
factory, exists := r.factories[pluginType]

View File

@@ -19,12 +19,11 @@ package main
import (
"os"
"sigs.k8s.io/kustomize/k8sdeps"
"sigs.k8s.io/kustomize/pkg/commands"
)
func main() {
if err := commands.NewDefaultCommand(k8sdeps.NewFactory()).Execute(); err != nil {
if err := commands.NewDefaultCommand().Execute(); err != nil {
os.Exit(1)
}
os.Exit(0)

View File

@@ -21,10 +21,10 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
"sigs.k8s.io/kustomize/pkg/loader"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/target"
)
@@ -67,7 +67,7 @@ func NewCmdBuild(
cmd := &cobra.Command{
Use: "build [path]",
Short: "Print current configuration per contents of " + constants.KustomizationFileNames[0],
Short: "Print current configuration per contents of " + pgmconfig.KustomizationFileNames[0],
Example: examples,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
@@ -88,7 +88,7 @@ func NewCmdBuild(
// Validate validates build command.
func (o *Options) Validate(args []string) error {
if len(args) > 1 {
return errors.New("specify one path to " + constants.KustomizationFileNames[0])
return errors.New("specify one path to " + pgmconfig.KustomizationFileNames[0])
}
if len(args) == 0 {
o.kustomizationPath = "./"

View File

@@ -19,7 +19,7 @@ package build
import (
"testing"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
)
func TestNewOptionsToSilenceCodeInspectionError(t *testing.T) {
@@ -39,7 +39,7 @@ func TestBuildValidate(t *testing.T) {
{"file", []string{"beans"}, "beans", ""},
{"path", []string{"a/b/c"}, "a/b/c", ""},
{"path", []string{"too", "many"},
"", "specify one path to " + constants.KustomizationFileNames[0]},
"", "specify one path to " + pgmconfig.KustomizationFileNames[0]},
}
for _, mycase := range cases {
opts := Options{}

View File

@@ -20,35 +20,57 @@ package commands
import (
"flag"
"os"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
"sigs.k8s.io/kustomize/k8sdeps/transformer"
"sigs.k8s.io/kustomize/k8sdeps/validator"
"sigs.k8s.io/kustomize/pkg/commands/build"
"sigs.k8s.io/kustomize/pkg/commands/edit"
"sigs.k8s.io/kustomize/pkg/commands/misc"
"sigs.k8s.io/kustomize/pkg/factory"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
"sigs.k8s.io/kustomize/pkg/types"
)
// NewDefaultCommand returns the default (aka root) command for kustomize command.
func NewDefaultCommand(f *factory.KustFactory) *cobra.Command {
fsys := fs.MakeRealFS()
func NewDefaultCommand() *cobra.Command {
fSys := fs.MakeRealFS()
stdOut := os.Stdout
c := &cobra.Command{
Use: "kustomize",
Short: "kustomize manages declarative configuration of Kubernetes",
Use: pgmconfig.PgmName,
Short: "Manages declarative configuration of Kubernetes",
Long: `
kustomize manages declarative configuration of Kubernetes.
Manages declarative configuration of Kubernetes.
See https://sigs.k8s.io/kustomize
`,
}
// Configuration for ConfigMap and Secret generators.
genMetaArgs := types.GeneratorMetaArgs{
PluginConfig: plugin.DefaultPluginConfig(),
}
c.Flags().BoolVar(
&genMetaArgs.PluginConfig.GoEnabled,
plugin.EnableGoPluginsFlagName,
false, plugin.EnableGoPluginsFlagHelp)
// Not advertising this alpha feature.
c.Flags().MarkHidden(plugin.EnableGoPluginsFlagName)
uf := kunstruct.NewKunstructuredFactoryWithGeneratorArgs(&genMetaArgs)
c.AddCommand(
// TODO: Make consistent API for newCmd* functions.
build.NewCmdBuild(stdOut, fsys, f.ResmapF, f.TransformerF),
edit.NewCmdEdit(fsys, f.ValidatorF, f.UnstructF),
misc.NewCmdConfig(fsys),
build.NewCmdBuild(
stdOut, fSys,
resmap.NewFactory(resource.NewFactory(uf)),
transformer.NewFactoryImpl()),
edit.NewCmdEdit(fSys, validator.NewKustValidator(), uf),
misc.NewCmdConfig(fSys),
misc.NewCmdVersion(stdOut),
)
c.PersistentFlags().AddGoFlagSet(flag.CommandLine)

View File

@@ -22,8 +22,8 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/commands/kustfile"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/types"
)
@@ -59,7 +59,7 @@ func newCmdAddAnnotation(fSys fs.FileSystem, v func(map[string]string) error) *c
o.mapValidator = v
cmd := &cobra.Command{
Use: "annotation",
Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileNames[0],
Short: "Adds one or more commonAnnotations to " + pgmconfig.KustomizationFileNames[0],
Example: `
add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`,
RunE: func(cmd *cobra.Command, args []string) error {
@@ -76,7 +76,7 @@ func newCmdAddLabel(fSys fs.FileSystem, v func(map[string]string) error) *cobra.
o.mapValidator = v
cmd := &cobra.Command{
Use: "label",
Short: "Adds one or more commonLabels to " + constants.KustomizationFileNames[0],
Short: "Adds one or more commonLabels to " + pgmconfig.KustomizationFileNames[0],
Example: `
add label {labelKey1:labelValue1},{labelKey2:labelValue2}`,
RunE: func(cmd *cobra.Command, args []string) error {

View File

@@ -27,8 +27,8 @@ import (
"strings"
"github.com/ghodss/yaml"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/types"
)
@@ -129,7 +129,7 @@ func NewKustomizationFile(fSys fs.FileSystem) (*kustomizationFile, error) { // n
func (mf *kustomizationFile) validate() error {
match := 0
var path []string
for _, kfilename := range constants.KustomizationFileNames {
for _, kfilename := range pgmconfig.KustomizationFileNames {
if mf.fSys.Exists(kfilename) {
match += 1
path = append(path, kfilename)
@@ -138,7 +138,7 @@ func (mf *kustomizationFile) validate() error {
switch match {
case 0:
return fmt.Errorf("Missing kustomization file '%s'.\n", constants.KustomizationFileNames[0])
return fmt.Errorf("Missing kustomization file '%s'.\n", pgmconfig.KustomizationFileNames[0])
case 1:
mf.path = path[0]
default:

View File

@@ -21,8 +21,8 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/types"
)
@@ -112,12 +112,12 @@ configMapGenerator:
name: my-configmap
`
fakeFS := fs.MakeFakeFS()
fakeFS.WriteFile(constants.KustomizationFileNames[1], []byte(kcontent))
fakeFS.WriteFile(pgmconfig.KustomizationFileNames[1], []byte(kcontent))
k, err := NewKustomizationFile(fakeFS)
if err != nil {
t.Fatalf("Unexpected Error: %v", err)
}
if k.path != constants.KustomizationFileNames[1] {
if k.path != pgmconfig.KustomizationFileNames[1] {
t.Fatalf("Load incorrect file path %s", k.path)
}
}

View File

@@ -1,39 +0,0 @@
/*
Copyright 2018 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 factory provides factories for kustomize.
package factory
import (
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
)
// KustFactory provides different factories for kustomize
type KustFactory struct {
ResmapF *resmap.Factory
TransformerF transformer.Factory
ValidatorF ifc.Validator
UnstructF ifc.KunstructuredFactory
}
// NewKustFactory creats a KustFactory instance
func NewKustFactory(u ifc.KunstructuredFactory, v ifc.Validator, t transformer.Factory) *KustFactory {
return &KustFactory{
ResmapF: resmap.NewFactory(resource.NewFactory(u)),
TransformerF: t,
ValidatorF: v,
UnstructF: u,
}
}

View File

@@ -22,7 +22,7 @@ import (
"sort"
"strings"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
)
var _ FileSystem = &fakeFs{}
@@ -158,7 +158,7 @@ func (fs *fakeFs) ReadFile(name string) ([]byte, error) {
}
func (fs *fakeFs) ReadTestKustomization() ([]byte, error) {
return fs.ReadFile(constants.KustomizationFileNames[0])
return fs.ReadFile(pgmconfig.KustomizationFileNames[0])
}
// WriteFile always succeeds and does nothing.
@@ -176,7 +176,7 @@ func (fs *fakeFs) WriteTestKustomization() {
// WriteTestKustomizationWith writes a standard test file.
func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) {
fs.WriteFile(constants.KustomizationFileNames[0], bytes)
fs.WriteFile(pgmconfig.KustomizationFileNames[0], bytes)
}
func (fs *fakeFs) pathMatch(path, pattern string) bool {

View File

@@ -25,8 +25,8 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/git"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/ifc"
@@ -341,7 +341,7 @@ func TestNewLoaderAtGitClone(t *testing.T) {
fSys.MkdirAll(coRoot)
fSys.MkdirAll(coRoot + "/" + pathInRepo)
fSys.WriteFile(
coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0],
coRoot+"/"+pathInRepo+"/"+pgmconfig.KustomizationFileNames[0],
[]byte(`
whatever
`))

54
pkg/pgmconfig/config.go Normal file
View File

@@ -0,0 +1,54 @@
/*
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 commands holds the CLI glue mapping textual commands/args to method calls.
package pgmconfig
import (
"os"
"path/filepath"
"runtime"
)
const (
XDG_CONFIG_HOME = "XDG_CONFIG_HOME"
defaultConfigSubdir = ".config"
)
// Use https://github.com/kirsle/configdir instead?
func ConfigRoot() string {
dir := os.Getenv(XDG_CONFIG_HOME)
if len(dir) == 0 {
dir = filepath.Join(
homeDir(), defaultConfigSubdir)
}
return filepath.Join(dir, PgmName)
}
func homeDir() string {
home := os.Getenv(homeEnv())
if len(home) > 0 {
return home
}
return "~"
}
func homeEnv() string {
if runtime.GOOS == "windows" {
return "USERPROFILE"
}
return "HOME"
}

View File

@@ -0,0 +1,56 @@
/*
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 pgmconfig
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestConfigDirNoXdg(t *testing.T) {
xdg, isSet := os.LookupEnv(XDG_CONFIG_HOME)
if isSet {
os.Unsetenv(XDG_CONFIG_HOME)
}
s := ConfigRoot()
if isSet {
os.Setenv(XDG_CONFIG_HOME, xdg)
}
if !strings.HasSuffix(
s,
rootedPath(defaultConfigSubdir, PgmName)) {
t.Fatalf("unexpected config dir: %s", s)
}
}
func rootedPath(elem ...string) string {
return string(filepath.Separator) + filepath.Join(elem...)
}
func TestConfigDirWithXdg(t *testing.T) {
xdg, isSet := os.LookupEnv(XDG_CONFIG_HOME)
os.Setenv(XDG_CONFIG_HOME, rootedPath("blah"))
s := ConfigRoot()
if isSet {
os.Setenv(XDG_CONFIG_HOME, xdg)
}
if s != rootedPath("blah", PgmName) {
t.Fatalf("unexpected config dir: %s", s)
}
}

View File

@@ -15,14 +15,18 @@ limitations under the License.
*/
// Package constants holds global constants for the kustomize tool.
package constants
package pgmconfig
// KustomizationFileNames is a list of filenames that can be recognized and consumbed
// by Kustomize.
// In each directory, Kustomize searches for file with the name in this list.
// Only one match is allowed.
// KustomizationFileNames is a list of filenames
// that kustomize recognizes.
// To avoid ambiguity, a directory cannot contain
// more than one match to this list.
var KustomizationFileNames = []string{
"kustomization.yaml",
"kustomization.yml",
"Kustomization",
}
const (
PgmName = "kustomize"
)

View File

@@ -14,6 +14,9 @@ limitations under the License.
package target_test
import (
"path/filepath"
"sigs.k8s.io/kustomize/pkg/types"
"strings"
"testing"
)
@@ -69,3 +72,47 @@ metadata:
name: shouldNotHaveHash
`)
}
func TestGoPluginNotEnabled(t *testing.T) {
th := NewKustTestHarness(t, "/app")
th.writeK("/app", `
secretGenerator:
- name: attemptGoPlugin
kvSources:
- name: foo
pluginType: go
args:
- someArg
- someOtherArg
`)
_, err := th.makeKustTarget().MakeCustomizedResMap()
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(), "enable go plugins by ") {
t.Fatalf("unexpected err: %v", err)
}
}
func TestGoPluginDoesNotExist(t *testing.T) {
th := NewKustTestHarnessWithPluginConfig(
t, "/app", types.PluginConfig{GoEnabled: true})
th.writeK("/app", `
secretGenerator:
- name: attemptGoPlugin
kvSources:
- name: foo
pluginType: go
args:
- someArg
- someOtherArg
`)
_, err := th.makeKustTarget().MakeCustomizedResMap()
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(),
filepath.Join("kvSources", "foo.so")) {
t.Fatalf("unexpected err: %v", err)
}
}

View File

@@ -25,11 +25,11 @@ import (
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
interror "sigs.k8s.io/kustomize/pkg/internal/error"
patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
"sigs.k8s.io/kustomize/pkg/transformers"
@@ -89,7 +89,7 @@ func commaOr(q []string) string {
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
var content []byte
match := 0
for _, kf := range constants.KustomizationFileNames {
for _, kf := range pgmconfig.KustomizationFileNames {
c, err := ldr.Load(kf)
if err == nil {
match += 1
@@ -100,7 +100,7 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) {
case 0:
return nil, fmt.Errorf(
"unable to find one of %v in directory '%s'",
commaOr(quoted(constants.KustomizationFileNames)), ldr.Root())
commaOr(quoted(pgmconfig.KustomizationFileNames)), ldr.Root())
case 1:
return content, nil
default:

View File

@@ -21,13 +21,14 @@ package target_test
import (
"fmt"
"path/filepath"
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
"strings"
"testing"
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/k8sdeps/transformer"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
"sigs.k8s.io/kustomize/pkg/pgmconfig"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
. "sigs.k8s.io/kustomize/pkg/target"
@@ -42,10 +43,18 @@ type KustTestHarness struct {
}
func NewKustTestHarness(t *testing.T, path string) *KustTestHarness {
return NewKustTestHarnessWithPluginConfig(
t, path, plugin.DefaultPluginConfig())
}
func NewKustTestHarnessWithPluginConfig(
t *testing.T, path string,
config types.PluginConfig) *KustTestHarness {
return &KustTestHarness{
t: t,
rf: resmap.NewFactory(resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())),
kunstruct.NewKunstructuredFactoryWithGeneratorArgs(
&types.GeneratorMetaArgs{PluginConfig: config}))),
ldr: loadertest.NewFakeLoader(path)}
}
@@ -66,7 +75,7 @@ func (th *KustTestHarness) writeF(dir string, content string) {
}
func (th *KustTestHarness) writeK(dir string, content string) {
th.writeF(filepath.Join(dir, constants.KustomizationFileNames[0]), `
th.writeF(filepath.Join(dir, pgmconfig.KustomizationFileNames[0]), `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
`+content)

View File

@@ -0,0 +1,170 @@
/*
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 target_test
import (
"testing"
)
func makeTransfomersImageBase(th *KustTestHarness) {
th.writeK("/app/base", `
resources:
- deploy1.yaml
- random.yaml
images:
- name: nginx
newTag: v2
- name: my-nginx
newTag: previous
- name: myprivaterepohostname:1234/my/image
newTag: v1.0.1
- name: foobar
digest: sha256:24a0c4b4
- name: alpine
newName: myprivaterepohostname:1234/my/cool-alpine
- name: gcr.io:8080/my-project/my-cool-app
newName: my-cool-app
- name: postgres
newName: my-postgres
newTag: v3
- name: docker
newName: my-docker
digest: sha256:25a0d4b4
`)
th.writeF("/app/base/deploy1.yaml", `
group: apps
apiVersion: v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
initContainers:
- name: nginx2
image: my-nginx:1.8.0
- name: init-alpine
image: alpine:1.8.0
containers:
- name: ngnix
image: nginx:1.7.9
- name: repliaced-with-digest
image: foobar:1
- name: postgresdb
image: postgres:1.8.0
`)
th.writeF("/app/base/random.yaml", `
kind: randomKind
metadata:
name: random
spec:
template:
spec:
containers:
- name: ngnix1
image: nginx
spec2:
template:
spec:
containers:
- name: nginx3
image: nginx:v1
- name: nginx4
image: my-nginx:latest
spec3:
template:
spec:
initContainers:
- name: postgresdb
image: postgres:alpine-9
- name: init-docker
image: docker:17-git
- name: myImage
image: myprivaterepohostname:1234/my/image:latest
- name: myImage2
image: myprivaterepohostname:1234/my/image
- name: my-app
image: my-app-image:v1
- name: my-cool-app
image: gcr.io:8080/my-project/my-cool-app:latest
`)
}
func TestTransfomersImageDefaultConfig(t *testing.T) {
th := NewKustTestHarness(t, "/app/base")
makeTransfomersImageBase(th)
m, err := th.makeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
th.assertActualEqualsExpected(m, `
apiVersion: v1
group: apps
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
containers:
- image: nginx:v2
name: ngnix
- image: foobar@sha256:24a0c4b4
name: repliaced-with-digest
- image: my-postgres:v3
name: postgresdb
initContainers:
- image: my-nginx:previous
name: nginx2
- image: myprivaterepohostname:1234/my/cool-alpine:1.8.0
name: init-alpine
---
kind: randomKind
metadata:
name: random
spec:
template:
spec:
containers:
- image: nginx:v2
name: ngnix1
spec2:
template:
spec:
containers:
- image: nginx:v2
name: nginx3
- image: my-nginx:previous
name: nginx4
spec3:
template:
spec:
initContainers:
- image: my-postgres:v3
name: postgresdb
- image: my-docker@sha256:25a0d4b4
name: init-docker
- image: myprivaterepohostname:1234/my/image:v1.0.1
name: myImage
- image: myprivaterepohostname:1234/my/image:v1.0.1
name: myImage2
- image: my-app-image:v1
name: my-app
- image: my-cool-app:latest
name: my-cool-app
`)
}

View File

@@ -19,98 +19,77 @@ package defaultconfig
const (
varReferenceFieldSpecs = `
varReference:
- path: spec/template/spec/initContainers/command
kind: StatefulSet
- path: spec/template/spec/containers/command
kind: StatefulSet
- path: spec/template/spec/initContainers/command
kind: Deployment
- path: spec/template/spec/containers/command
kind: Deployment
- path: spec/template/spec/initContainers/command
kind: DaemonSet
- path: spec/template/spec/containers/command
kind: DaemonSet
- path: spec/template/spec/containers/command
kind: Job
- path: spec/jobTemplate/spec/template/spec/containers/args
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/command
kind: CronJob
- path: spec/template/spec/initContainers/args
kind: StatefulSet
- path: spec/template/spec/containers/args
kind: StatefulSet
- path: spec/template/spec/initContainers/args
kind: Deployment
- path: spec/template/spec/containers/args
kind: Deployment
- path: spec/template/spec/initContainers/args
kind: DaemonSet
- path: spec/template/spec/containers/args
kind: DaemonSet
- path: spec/template/spec/containers/args
kind: Job
- path: spec/jobTemplate/spec/template/spec/containers/args
kind: CronJob
- path: spec/template/spec/initContainers/env/value
kind: StatefulSet
- path: spec/template/spec/containers/env/value
kind: StatefulSet
- path: spec/template/spec/initContainers/env/value
kind: Deployment
- path: spec/template/spec/containers/env/value
kind: Deployment
- path: spec/template/spec/initContainers/env/value
kind: DaemonSet
- path: spec/template/spec/containers/env/value
kind: DaemonSet
- path: spec/template/spec/containers/env/value
kind: Job
- path: spec/template/spec/initContainers/env/value
kind: Job
- path: spec/jobTemplate/spec/template/spec/containers/env/value
kind: CronJob
- path: spec/containers/command
kind: Pod
- path: spec/jobTemplate/spec/template/spec/containers/volumeMounts/mountPath
kind: CronJob
- path: spec/containers/args
kind: Pod
- path: spec/jobTemplate/spec/template/spec/initContainers/args
kind: CronJob
- path: spec/containers/env/value
kind: Pod
- path: spec/jobTemplate/spec/template/spec/initContainers/command
kind: CronJob
- path: spec/initContainers/command
kind: Pod
- path: spec/jobTemplate/spec/template/spec/initContainers/env/value
kind: CronJob
- path: spec/initContainers/args
kind: Pod
- path: spec/jobTemplate/spec/template/spec/initContainers/volumeMounts/mountPath
kind: CronJob
- path: spec/initContainers/env/value
kind: Pod
- path: spec/template/spec/containers/args
kind: DaemonSet
- path: spec/template/spec/containers/command
kind: DaemonSet
- path: spec/template/spec/containers/env/value
kind: DaemonSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/initContainers/args
kind: DaemonSet
- path: spec/template/spec/initContainers/command
kind: DaemonSet
- path: spec/template/spec/initContainers/env/value
kind: DaemonSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/containers/args
kind: Deployment
- path: spec/template/spec/containers/command
kind: Deployment
- path: spec/template/spec/containers/env/value
kind: Deployment
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: Deployment
- path: spec/template/spec/initContainers/args
kind: Deployment
- path: spec/template/spec/initContainers/command
kind: Deployment
- path: spec/template/spec/initContainers/env/value
kind: Deployment
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: Deployment
- path: spec/rules/host
kind: Ingress
@@ -118,47 +97,101 @@ varReference:
- path: spec/tls/hosts
kind: Ingress
- path: spec/template/spec/containers/args
kind: Job
- path: spec/template/spec/containers/command
kind: Job
- path: spec/template/spec/containers/env/value
kind: Job
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: StatefulSet
kind: Job
- path: spec/template/spec/initContainers/args
kind: Job
- path: spec/template/spec/initContainers/command
kind: Job
- path: spec/template/spec/initContainers/env/value
kind: Job
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: StatefulSet
kind: Job
- path: spec/containers/args
kind: Pod
- path: spec/containers/command
kind: Pod
- path: spec/containers/env/value
kind: Pod
- path: spec/containers/volumeMounts/mountPath
kind: Pod
- path: spec/initContainers/args
kind: Pod
- path: spec/initContainers/command
kind: Pod
- path: spec/initContainers/env/value
kind: Pod
- path: spec/initContainers/volumeMounts/mountPath
kind: Pod
- path: spec/template/spec/containers/args
kind: ReplicaSet
- path: spec/template/spec/containers/command
kind: ReplicaSet
- path: spec/template/spec/containers/env/value
kind: ReplicaSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: ReplicaSet
- path: spec/template/spec/initContainers/args
kind: ReplicaSet
- path: spec/template/spec/initContainers/command
kind: ReplicaSet
- path: spec/template/spec/initContainers/env/value
kind: ReplicaSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: ReplicaSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: Job
- path: spec/template/spec/containers/args
kind: StatefulSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: Job
- path: spec/template/spec/containers/command
kind: StatefulSet
- path: spec/template/spec/containers/env/value
kind: StatefulSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: CronJob
kind: StatefulSet
- path: spec/template/spec/initContainers/args
kind: StatefulSet
- path: spec/template/spec/initContainers/command
kind: StatefulSet
- path: spec/template/spec/initContainers/env/value
kind: StatefulSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: CronJob
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: Deployment
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: Deployment
kind: StatefulSet
- path: metadata/labels
`

View File

@@ -1,266 +0,0 @@
/*
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 transformers
import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/pkg/gvk"
"sigs.k8s.io/kustomize/pkg/image"
"sigs.k8s.io/kustomize/pkg/resid"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
)
func TestImageTransformer(t *testing.T) {
var rf = resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl())
m := resmap.ResMap{
resid.NewResId(deploy, "deploy1"): rf.FromMap(
map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"initContainers": []interface{}{
map[string]interface{}{
"name": "nginx2",
"image": "my-nginx:1.8.0",
},
map[string]interface{}{
"name": "init-alpine",
"image": "alpine:1.8.0",
},
},
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
map[string]interface{}{
"name": "replaced-with-digest",
"image": "foobar:1",
},
map[string]interface{}{
"name": "postgresdb",
"image": "postgres:1.8.0",
},
},
},
},
},
}),
resid.NewResId(gvk.Gvk{Kind: "randomKind"}, "random"): rf.FromMap(
map[string]interface{}{
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx1",
"image": "nginx",
},
},
},
},
},
"spec2": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx3",
"image": "nginx:v1",
},
map[string]interface{}{
"name": "nginx4",
"image": "my-nginx:latest",
},
},
},
},
},
"spec3": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"initContainers": []interface{}{
map[string]interface{}{
"name": "postgresdb",
"image": "postgres:alpine-9",
},
map[string]interface{}{
"name": "init-docker",
"image": "docker:17-git",
},
map[string]interface{}{
"name": "myimage",
"image": "myprivaterepohostname:1234/my/image:latest",
},
map[string]interface{}{
"name": "myimage2",
"image": "myprivaterepohostname:1234/my/image",
},
map[string]interface{}{
"name": "my-app",
"image": "my-app-image:v1",
},
map[string]interface{}{
"name": "my-cool-app",
"image": "gcr.io:8080/my-project/my-cool-app:latest",
},
},
},
},
},
}),
}
expected := resmap.ResMap{
resid.NewResId(deploy, "deploy1"): rf.FromMap(
map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"initContainers": []interface{}{
map[string]interface{}{
"name": "nginx2",
"image": "my-nginx:previous",
},
map[string]interface{}{
"name": "init-alpine",
"image": "myprivaterepohostname:1234/my/cool-alpine:1.8.0",
},
},
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:v2",
},
map[string]interface{}{
"name": "replaced-with-digest",
"image": "foobar@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
},
map[string]interface{}{
"name": "postgresdb",
"image": "my-postgres:v3",
},
},
},
},
},
}),
resid.NewResId(gvk.Gvk{Kind: "randomKind"}, "random"): rf.FromMap(
map[string]interface{}{
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx1",
"image": "nginx:v2",
},
},
},
},
},
"spec2": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx3",
"image": "nginx:v2",
},
map[string]interface{}{
"name": "nginx4",
"image": "my-nginx:previous",
},
},
},
},
},
"spec3": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"initContainers": []interface{}{
map[string]interface{}{
"name": "postgresdb",
"image": "my-postgres:v3",
},
map[string]interface{}{
"name": "init-docker",
"image": "my-docker@sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
},
map[string]interface{}{
"name": "myimage",
"image": "myprivaterepohostname:1234/my/image:v1.0.1",
},
map[string]interface{}{
"name": "myimage2",
"image": "myprivaterepohostname:1234/my/image:v1.0.1",
},
map[string]interface{}{
"name": "my-app",
"image": "gcr.io/my-project/my-app-image:v1",
},
map[string]interface{}{
"name": "my-cool-app",
"image": "my-cool-app:latest",
},
},
},
},
},
}),
}
it, err := NewImageTransformer([]image.Image{
{Name: "nginx", NewTag: "v2"},
{Name: "my-nginx", NewTag: "previous"},
{Name: "myprivaterepohostname:1234/my/image", NewTag: "v1.0.1"},
{Name: "foobar", Digest: "sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
{Name: "alpine", NewName: "myprivaterepohostname:1234/my/cool-alpine"},
{Name: "my-app-image", NewName: "gcr.io/my-project/my-app-image"},
{Name: "gcr.io:8080/my-project/my-cool-app", NewName: "my-cool-app"},
{Name: "postgres", NewName: "my-postgres", NewTag: "v3"},
{Name: "docker", NewName: "my-docker", Digest: "sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = it.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
err = expected.ErrorIfNotEqual(m)
t.Fatalf("actual doesn't match expected: %v. Actual %+v", err, m)
}
}

View File

@@ -194,6 +194,25 @@ type GeneratorArgs struct {
KVSources []KVSource `json:",inline,omitempty" yaml:",inline,omitempty"`
}
// GeneratorMetaArgs contains arguments common to generators
// that come from somewhere other than a kustomization file.
type GeneratorMetaArgs struct {
PluginConfig PluginConfig
}
// PluginConfig holds plugin configuration.
type PluginConfig struct {
// DirectoryPath is an absolute path to a
// directory containing kustomize plugins.
// This directory may contain subdirectories
// further categorizing plugins.
DirectoryPath string
// GoEnabled is true if goplugins are enabled.
// See https://golang.org/pkg/plugin
GoEnabled bool
}
// ConfigMapArgs contains the metadata of how to generate a configmap.
type ConfigMapArgs struct {
// GeneratorArgs for the configmap.