Merge pull request #887 from monopole/addNannyFlag

Put goplugins behind flag.
This commit is contained in:
Jeff Regan
2019-03-17 13:46:03 -07:00
committed by GitHub
22 changed files with 337 additions and 140 deletions

View File

@@ -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

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. // 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
} }

View File

@@ -18,40 +18,66 @@ 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 (
pluginDir = "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
} }
func configDir() string {
xdghome := os.Getenv("XDG_CONFIG_HOME")
if len(xdghome) == 0 {
return os.ExpandEnv("$HOME/.config")
}
return xdghome
}
func (p *goFactory) load(name string) (KVSource, error) { func (p *goFactory) load(name string) (KVSource, error) {
if plug, ok := p.plugins[name]; ok { if plug, ok := p.plugins[name]; ok {
return plug, nil return plug, nil
} }
goPlugin, err := plugin.Open(fmt.Sprintf("%s/%s/kustomize-%s.so", configDir(), pluginDir, 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
} }

View File

@@ -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),
"testonly": newTestonlyFactory(), "testonly": newTestonlyFactory(),
}, },
} }
} }
// 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]

View File

@@ -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)

View File

@@ -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 = "./"

View File

@@ -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{}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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:

View File

@@ -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)
} }
} }

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" "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 {

View File

@@ -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
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 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"
)

View File

@@ -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)
}
}

View File

@@ -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:

View File

@@ -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)

View File

@@ -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.