mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
Merge branch 'master' into builtins
This commit is contained in:
@@ -1,37 +1,46 @@
|
|||||||
# Transformer Configurations
|
# Transformer Configurations
|
||||||
|
|
||||||
Kustomize computes the resources by applying a series of transformers:
|
Kustomize creates new resources by applying a series of transformations to an original
|
||||||
- namespace transformer
|
set of resources. Kustomize provides the following default transformers:
|
||||||
- prefix/suffix transformer
|
|
||||||
- label transformer
|
|
||||||
- annotation transformer
|
|
||||||
- name reference transformer
|
|
||||||
- variable reference transformer
|
|
||||||
|
|
||||||
Each transformer takes a list of resources and modifies certain fields. The modification is based on the transformer's rule.
|
- namespace
|
||||||
The fields to update is the transformer's configuration, which is a list of filedspec that can be represented in YAML format.
|
- prefix/suffix
|
||||||
|
- label
|
||||||
|
- annotation
|
||||||
|
- name reference
|
||||||
|
- variable reference
|
||||||
|
|
||||||
## fieldSpec
|
A `fieldSpec` list, in a transformer's configuration, determines which resource types and which fields
|
||||||
FieldSpec is a type to represent a path to a field in one kind of resources. It has following format
|
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
|
group: some-group
|
||||||
version: some-version
|
version: some-version
|
||||||
kind: some-kind
|
kind: some-kind
|
||||||
path: path/to/the/field
|
path: path/to/the/field
|
||||||
create: false
|
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
|
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.
|
||||||
Name prefix suffix transformer adds prefix and suffix to the `metadata/name` field for all resources with following configuration:
|
|
||||||
```
|
## 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:
|
namePrefix:
|
||||||
- path: metadata/name
|
- path: metadata/name
|
||||||
```
|
```
|
||||||
|
|
||||||
## label transformer
|
## 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.
|
|
||||||
```
|
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:
|
commonLabels:
|
||||||
- path: metadata/labels
|
- path: metadata/labels
|
||||||
create: true
|
create: true
|
||||||
@@ -44,15 +53,16 @@ commonLabels:
|
|||||||
- path: spec/selector/matchLabels
|
- path: spec/selector/matchLabels
|
||||||
create: true
|
create: true
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
(etc.)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## name reference transformer
|
## 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'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
|
kind: ConfigMap
|
||||||
version: v1
|
version: v1
|
||||||
FieldSpecs:
|
fieldSpecs:
|
||||||
- kind: Pod
|
- kind: Pod
|
||||||
version: v1
|
version: v1
|
||||||
path: spec/volumes/configMap/name
|
path: spec/volumes/configMap/name
|
||||||
@@ -60,10 +70,11 @@ FieldSpecs:
|
|||||||
path: spec/template/spec/volumes/configMap/name
|
path: spec/template/spec/volumes/configMap/name
|
||||||
- kind: Job
|
- kind: Job
|
||||||
path: spec/template/spec/volumes/configMap/name
|
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:
|
nameReference:
|
||||||
- kind: ConfigMap
|
- kind: ConfigMap
|
||||||
version: v1
|
version: v1
|
||||||
@@ -74,7 +85,7 @@ nameReference:
|
|||||||
- path: spec/containers/env/valueFrom/configMapKeyRef/name
|
- path: spec/containers/env/valueFrom/configMapKeyRef/name
|
||||||
version: v1
|
version: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
(etc.)
|
# ...
|
||||||
- kind: Secret
|
- kind: Secret
|
||||||
version: v1
|
version: v1
|
||||||
fieldSpecs:
|
fieldSpecs:
|
||||||
@@ -84,12 +95,12 @@ nameReference:
|
|||||||
- path: spec/containers/env/valueFrom/secretKeyRef/name
|
- path: spec/containers/env/valueFrom/secretKeyRef/name
|
||||||
version: v1
|
version: v1
|
||||||
kind: Pod
|
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)
|
- [support a CRD type](crd/README.md)
|
||||||
- add extra fields for variable substitution
|
- add extra fields for variable substitution
|
||||||
- add extra fields for name reference
|
- add extra fields for name reference
|
||||||
@@ -21,8 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
"sigs.k8s.io/kustomize/pkg/types"
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
@@ -40,8 +39,8 @@ func NewFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeFreshConfigMap(
|
func makeFreshConfigMap(
|
||||||
args *types.ConfigMapArgs) *corev1.ConfigMap {
|
args *types.ConfigMapArgs) *v1.ConfigMap {
|
||||||
cm := &corev1.ConfigMap{}
|
cm := &v1.ConfigMap{}
|
||||||
cm.APIVersion = "v1"
|
cm.APIVersion = "v1"
|
||||||
cm.Kind = "ConfigMap"
|
cm.Kind = "ConfigMap"
|
||||||
cm.Name = args.Name
|
cm.Name = args.Name
|
||||||
@@ -52,7 +51,7 @@ func makeFreshConfigMap(
|
|||||||
|
|
||||||
// MakeConfigMap returns a new ConfigMap, or nil and an error.
|
// MakeConfigMap returns a new ConfigMap, or nil and an error.
|
||||||
func (f *Factory) MakeConfigMap(
|
func (f *Factory) MakeConfigMap(
|
||||||
args *types.ConfigMapArgs) (*corev1.ConfigMap, error) {
|
args *types.ConfigMapArgs) (*v1.ConfigMap, error) {
|
||||||
all, err := f.loadKvPairs(args.GeneratorArgs)
|
all, err := f.loadKvPairs(args.GeneratorArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -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(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -32,13 +32,21 @@ import (
|
|||||||
|
|
||||||
// KunstructuredFactoryImpl hides construction using apimachinery types.
|
// KunstructuredFactoryImpl hides construction using apimachinery types.
|
||||||
type KunstructuredFactoryImpl struct {
|
type KunstructuredFactoryImpl struct {
|
||||||
|
generatorMetaArgs *types.GeneratorMetaArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
|
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
|
||||||
|
|
||||||
// NewKunstructuredFactoryImpl returns a factory.
|
// NewKunstructuredFactoryImpl returns a factory.
|
||||||
func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory {
|
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.
|
// SliceFromBytes returns a slice of Kunstructured.
|
||||||
@@ -82,7 +90,10 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap(
|
|||||||
ldr ifc.Loader,
|
ldr ifc.Loader,
|
||||||
options *types.GeneratorOptions,
|
options *types.GeneratorOptions,
|
||||||
args *types.ConfigMapArgs) (ifc.Kunstructured, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -94,7 +105,10 @@ func (kf *KunstructuredFactoryImpl) MakeSecret(
|
|||||||
ldr ifc.Loader,
|
ldr ifc.Loader,
|
||||||
options *types.GeneratorOptions,
|
options *types.GeneratorOptions,
|
||||||
args *types.SecretArgs) (ifc.Kunstructured, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,23 +18,45 @@ package plugin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"path/filepath"
|
||||||
"plugin"
|
"plugin"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Factory = &goFactory{}
|
var _ Factory = &goFactory{}
|
||||||
|
|
||||||
const (
|
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{
|
return &goFactory{
|
||||||
|
config: c,
|
||||||
plugins: make(map[string]KVSource),
|
plugins: make(map[string]KVSource),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type goFactory struct {
|
type goFactory struct {
|
||||||
|
config *types.PluginConfig
|
||||||
plugins map[string]KVSource
|
plugins map[string]KVSource
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +65,19 @@ func (p *goFactory) load(name string) (KVSource, error) {
|
|||||||
return plug, nil
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package plugin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registry holds all the plugin factories.
|
// Registry holds all the plugin factories.
|
||||||
@@ -28,17 +30,36 @@ type Registry struct {
|
|||||||
ldr ifc.Loader
|
ldr ifc.Loader
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegistry returns a new Registry loaded with all the factories.
|
const (
|
||||||
func NewRegistry(ldr ifc.Loader) Registry {
|
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{
|
return Registry{
|
||||||
ldr: ldr,
|
ldr: ldr,
|
||||||
factories: map[string]Factory{
|
factories: map[string]Factory{
|
||||||
"go": newGoFactory(),
|
"go": newGoFactory(pc),
|
||||||
"builtin": newBuiltinFactory(ldr),
|
"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,
|
// Load returns a plugin by type and name,
|
||||||
func (r *Registry) Load(pluginType, name string) (KVSource, error) {
|
func (r *Registry) Load(pluginType, name string) (KVSource, error) {
|
||||||
factory, exists := r.factories[pluginType]
|
factory, exists := r.factories[pluginType]
|
||||||
|
|||||||
@@ -19,12 +19,11 @@ package main
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/k8sdeps"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/commands"
|
"sigs.k8s.io/kustomize/pkg/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := commands.NewDefaultCommand(k8sdeps.NewFactory()).Execute(); err != nil {
|
if err := commands.NewDefaultCommand().Execute(); err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
||||||
"sigs.k8s.io/kustomize/pkg/loader"
|
"sigs.k8s.io/kustomize/pkg/loader"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
"sigs.k8s.io/kustomize/pkg/target"
|
"sigs.k8s.io/kustomize/pkg/target"
|
||||||
)
|
)
|
||||||
@@ -67,7 +67,7 @@ func NewCmdBuild(
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "build [path]",
|
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,
|
Example: examples,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
@@ -88,7 +88,7 @@ func NewCmdBuild(
|
|||||||
// Validate validates build command.
|
// Validate validates build command.
|
||||||
func (o *Options) Validate(args []string) error {
|
func (o *Options) Validate(args []string) error {
|
||||||
if len(args) > 1 {
|
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 {
|
if len(args) == 0 {
|
||||||
o.kustomizationPath = "./"
|
o.kustomizationPath = "./"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package build
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewOptionsToSilenceCodeInspectionError(t *testing.T) {
|
func TestNewOptionsToSilenceCodeInspectionError(t *testing.T) {
|
||||||
@@ -39,7 +39,7 @@ func TestBuildValidate(t *testing.T) {
|
|||||||
{"file", []string{"beans"}, "beans", ""},
|
{"file", []string{"beans"}, "beans", ""},
|
||||||
{"path", []string{"a/b/c"}, "a/b/c", ""},
|
{"path", []string{"a/b/c"}, "a/b/c", ""},
|
||||||
{"path", []string{"too", "many"},
|
{"path", []string{"too", "many"},
|
||||||
"", "specify one path to " + constants.KustomizationFileNames[0]},
|
"", "specify one path to " + pgmconfig.KustomizationFileNames[0]},
|
||||||
}
|
}
|
||||||
for _, mycase := range cases {
|
for _, mycase := range cases {
|
||||||
opts := Options{}
|
opts := Options{}
|
||||||
|
|||||||
@@ -20,35 +20,57 @@ package commands
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"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/build"
|
||||||
"sigs.k8s.io/kustomize/pkg/commands/edit"
|
"sigs.k8s.io/kustomize/pkg/commands/edit"
|
||||||
"sigs.k8s.io/kustomize/pkg/commands/misc"
|
"sigs.k8s.io/kustomize/pkg/commands/misc"
|
||||||
"sigs.k8s.io/kustomize/pkg/factory"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"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.
|
// NewDefaultCommand returns the default (aka root) command for kustomize command.
|
||||||
func NewDefaultCommand(f *factory.KustFactory) *cobra.Command {
|
func NewDefaultCommand() *cobra.Command {
|
||||||
fsys := fs.MakeRealFS()
|
fSys := fs.MakeRealFS()
|
||||||
stdOut := os.Stdout
|
stdOut := os.Stdout
|
||||||
|
|
||||||
c := &cobra.Command{
|
c := &cobra.Command{
|
||||||
Use: "kustomize",
|
Use: pgmconfig.PgmName,
|
||||||
Short: "kustomize manages declarative configuration of Kubernetes",
|
Short: "Manages declarative configuration of Kubernetes",
|
||||||
Long: `
|
Long: `
|
||||||
kustomize manages declarative configuration of Kubernetes.
|
Manages declarative configuration of Kubernetes.
|
||||||
|
|
||||||
See https://sigs.k8s.io/kustomize
|
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(
|
c.AddCommand(
|
||||||
// TODO: Make consistent API for newCmd* functions.
|
build.NewCmdBuild(
|
||||||
build.NewCmdBuild(stdOut, fsys, f.ResmapF, f.TransformerF),
|
stdOut, fSys,
|
||||||
edit.NewCmdEdit(fsys, f.ValidatorF, f.UnstructF),
|
resmap.NewFactory(resource.NewFactory(uf)),
|
||||||
misc.NewCmdConfig(fsys),
|
transformer.NewFactoryImpl()),
|
||||||
|
edit.NewCmdEdit(fSys, validator.NewKustValidator(), uf),
|
||||||
|
misc.NewCmdConfig(fSys),
|
||||||
misc.NewCmdVersion(stdOut),
|
misc.NewCmdVersion(stdOut),
|
||||||
)
|
)
|
||||||
c.PersistentFlags().AddGoFlagSet(flag.CommandLine)
|
c.PersistentFlags().AddGoFlagSet(flag.CommandLine)
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/pkg/commands/kustfile"
|
"sigs.k8s.io/kustomize/pkg/commands/kustfile"
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/types"
|
"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
|
o.mapValidator = v
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "annotation",
|
Use: "annotation",
|
||||||
Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileNames[0],
|
Short: "Adds one or more commonAnnotations to " + pgmconfig.KustomizationFileNames[0],
|
||||||
Example: `
|
Example: `
|
||||||
add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`,
|
add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
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
|
o.mapValidator = v
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "label",
|
Use: "label",
|
||||||
Short: "Adds one or more commonLabels to " + constants.KustomizationFileNames[0],
|
Short: "Adds one or more commonLabels to " + pgmconfig.KustomizationFileNames[0],
|
||||||
Example: `
|
Example: `
|
||||||
add label {labelKey1:labelValue1},{labelKey2:labelValue2}`,
|
add label {labelKey1:labelValue1},{labelKey2:labelValue2}`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/types"
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ func NewKustomizationFile(fSys fs.FileSystem) (*kustomizationFile, error) { // n
|
|||||||
func (mf *kustomizationFile) validate() error {
|
func (mf *kustomizationFile) validate() error {
|
||||||
match := 0
|
match := 0
|
||||||
var path []string
|
var path []string
|
||||||
for _, kfilename := range constants.KustomizationFileNames {
|
for _, kfilename := range pgmconfig.KustomizationFileNames {
|
||||||
if mf.fSys.Exists(kfilename) {
|
if mf.fSys.Exists(kfilename) {
|
||||||
match += 1
|
match += 1
|
||||||
path = append(path, kfilename)
|
path = append(path, kfilename)
|
||||||
@@ -138,7 +138,7 @@ func (mf *kustomizationFile) validate() error {
|
|||||||
|
|
||||||
switch match {
|
switch match {
|
||||||
case 0:
|
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:
|
case 1:
|
||||||
mf.path = path[0]
|
mf.path = path[0]
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/types"
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -112,12 +112,12 @@ configMapGenerator:
|
|||||||
name: my-configmap
|
name: my-configmap
|
||||||
`
|
`
|
||||||
fakeFS := fs.MakeFakeFS()
|
fakeFS := fs.MakeFakeFS()
|
||||||
fakeFS.WriteFile(constants.KustomizationFileNames[1], []byte(kcontent))
|
fakeFS.WriteFile(pgmconfig.KustomizationFileNames[1], []byte(kcontent))
|
||||||
k, err := NewKustomizationFile(fakeFS)
|
k, err := NewKustomizationFile(fakeFS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
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)
|
t.Fatalf("Load incorrect file path %s", k.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ FileSystem = &fakeFs{}
|
var _ FileSystem = &fakeFs{}
|
||||||
@@ -158,7 +158,7 @@ func (fs *fakeFs) ReadFile(name string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fs *fakeFs) ReadTestKustomization() ([]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.
|
// WriteFile always succeeds and does nothing.
|
||||||
@@ -176,7 +176,7 @@ func (fs *fakeFs) WriteTestKustomization() {
|
|||||||
|
|
||||||
// WriteTestKustomizationWith writes a standard test file.
|
// WriteTestKustomizationWith writes a standard test file.
|
||||||
func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) {
|
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 {
|
func (fs *fakeFs) pathMatch(path, pattern string) bool {
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/git"
|
"sigs.k8s.io/kustomize/pkg/git"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
@@ -341,7 +341,7 @@ func TestNewLoaderAtGitClone(t *testing.T) {
|
|||||||
fSys.MkdirAll(coRoot)
|
fSys.MkdirAll(coRoot)
|
||||||
fSys.MkdirAll(coRoot + "/" + pathInRepo)
|
fSys.MkdirAll(coRoot + "/" + pathInRepo)
|
||||||
fSys.WriteFile(
|
fSys.WriteFile(
|
||||||
coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0],
|
coRoot+"/"+pathInRepo+"/"+pgmconfig.KustomizationFileNames[0],
|
||||||
[]byte(`
|
[]byte(`
|
||||||
whatever
|
whatever
|
||||||
`))
|
`))
|
||||||
|
|||||||
54
pkg/pgmconfig/config.go
Normal file
54
pkg/pgmconfig/config.go
Normal 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"
|
||||||
|
}
|
||||||
56
pkg/pgmconfig/config_test.go
Normal file
56
pkg/pgmconfig/config_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,14 +15,18 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Package constants holds global constants for the kustomize tool.
|
// 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
|
// KustomizationFileNames is a list of filenames
|
||||||
// by Kustomize.
|
// that kustomize recognizes.
|
||||||
// In each directory, Kustomize searches for file with the name in this list.
|
// To avoid ambiguity, a directory cannot contain
|
||||||
// Only one match is allowed.
|
// more than one match to this list.
|
||||||
var KustomizationFileNames = []string{
|
var KustomizationFileNames = []string{
|
||||||
"kustomization.yaml",
|
"kustomization.yaml",
|
||||||
"kustomization.yml",
|
"kustomization.yml",
|
||||||
"Kustomization",
|
"Kustomization",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PgmName = "kustomize"
|
||||||
|
)
|
||||||
@@ -14,6 +14,9 @@ limitations under the License.
|
|||||||
package target_test
|
package target_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,3 +72,47 @@ metadata:
|
|||||||
name: shouldNotHaveHash
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ import (
|
|||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
||||||
interror "sigs.k8s.io/kustomize/pkg/internal/error"
|
interror "sigs.k8s.io/kustomize/pkg/internal/error"
|
||||||
patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer"
|
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/resmap"
|
||||||
"sigs.k8s.io/kustomize/pkg/resource"
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||||
@@ -89,7 +89,7 @@ func commaOr(q []string) string {
|
|||||||
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
||||||
var content []byte
|
var content []byte
|
||||||
match := 0
|
match := 0
|
||||||
for _, kf := range constants.KustomizationFileNames {
|
for _, kf := range pgmconfig.KustomizationFileNames {
|
||||||
c, err := ldr.Load(kf)
|
c, err := ldr.Load(kf)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
match += 1
|
match += 1
|
||||||
@@ -100,7 +100,7 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
|||||||
case 0:
|
case 0:
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"unable to find one of %v in directory '%s'",
|
"unable to find one of %v in directory '%s'",
|
||||||
commaOr(quoted(constants.KustomizationFileNames)), ldr.Root())
|
commaOr(quoted(pgmconfig.KustomizationFileNames)), ldr.Root())
|
||||||
case 1:
|
case 1:
|
||||||
return content, nil
|
return content, nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ package target_test
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
|
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
|
||||||
"sigs.k8s.io/kustomize/k8sdeps/transformer"
|
"sigs.k8s.io/kustomize/k8sdeps/transformer"
|
||||||
"sigs.k8s.io/kustomize/pkg/constants"
|
|
||||||
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
|
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
"sigs.k8s.io/kustomize/pkg/resource"
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
. "sigs.k8s.io/kustomize/pkg/target"
|
. "sigs.k8s.io/kustomize/pkg/target"
|
||||||
@@ -42,10 +43,18 @@ type KustTestHarness struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewKustTestHarness(t *testing.T, path string) *KustTestHarness {
|
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{
|
return &KustTestHarness{
|
||||||
t: t,
|
t: t,
|
||||||
rf: resmap.NewFactory(resource.NewFactory(
|
rf: resmap.NewFactory(resource.NewFactory(
|
||||||
kunstruct.NewKunstructuredFactoryImpl())),
|
kunstruct.NewKunstructuredFactoryWithGeneratorArgs(
|
||||||
|
&types.GeneratorMetaArgs{PluginConfig: config}))),
|
||||||
ldr: loadertest.NewFakeLoader(path)}
|
ldr: loadertest.NewFakeLoader(path)}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +75,7 @@ func (th *KustTestHarness) writeF(dir string, content string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (th *KustTestHarness) writeK(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
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
`+content)
|
`+content)
|
||||||
|
|||||||
170
pkg/target/transformersimage_test.go
Normal file
170
pkg/target/transformersimage_test.go
Normal 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
|
||||||
|
`)
|
||||||
|
}
|
||||||
@@ -19,98 +19,77 @@ package defaultconfig
|
|||||||
const (
|
const (
|
||||||
varReferenceFieldSpecs = `
|
varReferenceFieldSpecs = `
|
||||||
varReference:
|
varReference:
|
||||||
- path: spec/template/spec/initContainers/command
|
- path: spec/jobTemplate/spec/template/spec/containers/args
|
||||||
kind: StatefulSet
|
kind: CronJob
|
||||||
|
|
||||||
- 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/command
|
- path: spec/jobTemplate/spec/template/spec/containers/command
|
||||||
kind: CronJob
|
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
|
- path: spec/jobTemplate/spec/template/spec/containers/env/value
|
||||||
kind: CronJob
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/containers/command
|
- path: spec/jobTemplate/spec/template/spec/containers/volumeMounts/mountPath
|
||||||
kind: Pod
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/containers/args
|
- path: spec/jobTemplate/spec/template/spec/initContainers/args
|
||||||
kind: Pod
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/containers/env/value
|
- path: spec/jobTemplate/spec/template/spec/initContainers/command
|
||||||
kind: Pod
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/initContainers/command
|
- path: spec/jobTemplate/spec/template/spec/initContainers/env/value
|
||||||
kind: Pod
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/initContainers/args
|
- path: spec/jobTemplate/spec/template/spec/initContainers/volumeMounts/mountPath
|
||||||
kind: Pod
|
kind: CronJob
|
||||||
|
|
||||||
- path: spec/initContainers/env/value
|
- path: spec/template/spec/containers/args
|
||||||
kind: Pod
|
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
|
- path: spec/rules/host
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
@@ -118,47 +97,101 @@ varReference:
|
|||||||
- path: spec/tls/hosts
|
- path: spec/tls/hosts
|
||||||
kind: Ingress
|
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
|
- 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
|
- 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
|
- path: spec/containers/volumeMounts/mountPath
|
||||||
kind: Pod
|
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
|
- path: spec/initContainers/volumeMounts/mountPath
|
||||||
kind: Pod
|
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
|
- path: spec/template/spec/containers/volumeMounts/mountPath
|
||||||
kind: ReplicaSet
|
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
|
- path: spec/template/spec/initContainers/volumeMounts/mountPath
|
||||||
kind: ReplicaSet
|
kind: ReplicaSet
|
||||||
|
|
||||||
- path: spec/template/spec/containers/volumeMounts/mountPath
|
- path: spec/template/spec/containers/args
|
||||||
kind: Job
|
kind: StatefulSet
|
||||||
|
|
||||||
- path: spec/template/spec/initContainers/volumeMounts/mountPath
|
- path: spec/template/spec/containers/command
|
||||||
kind: Job
|
kind: StatefulSet
|
||||||
|
|
||||||
|
- path: spec/template/spec/containers/env/value
|
||||||
|
kind: StatefulSet
|
||||||
|
|
||||||
- path: spec/template/spec/containers/volumeMounts/mountPath
|
- 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
|
- path: spec/template/spec/initContainers/volumeMounts/mountPath
|
||||||
kind: CronJob
|
kind: StatefulSet
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
- path: metadata/labels
|
- path: metadata/labels
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -194,6 +194,25 @@ type GeneratorArgs struct {
|
|||||||
KVSources []KVSource `json:",inline,omitempty" yaml:",inline,omitempty"`
|
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.
|
// ConfigMapArgs contains the metadata of how to generate a configmap.
|
||||||
type ConfigMapArgs struct {
|
type ConfigMapArgs struct {
|
||||||
// GeneratorArgs for the configmap.
|
// GeneratorArgs for the configmap.
|
||||||
|
|||||||
Reference in New Issue
Block a user