diff --git a/go.mod b/go.mod index bcffc8073d..b53b870c5e 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/spf13/cobra v0.0.2 github.com/spf13/pflag v1.0.1 github.com/stretchr/testify v1.3.0 // indirect - golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d // indirect + golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.2.1 k8s.io/api v0.0.0-20180510062335-53d615ae3f44 diff --git a/go.sum b/go.sum index 7fc814bb93..bde16bf76e 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,8 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d h1:bt+R27hbE7uVf7PY9S6wpNg9Xo2WRe/XQT0uGq9RQQw= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 h1:sU3tSV6wDhWsvf9NjL0FzRjgAmYnQL5NEhdmcN16UEg= +golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index fc1cbd3722..ca95bef602 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -1,4 +1,4 @@ -/// Copyright 2019 The Kubernetes Authors. +// Copyright 2019 The Kubernetes Authors. // SPDX-License-Identifier: Apache-2.0 package build @@ -28,6 +28,7 @@ type Options struct { kustomizationPath string outputPath string loadRestrictor loader.LoadRestrictorFunc + outOrder reorderOutput } // NewOptions creates a Options object @@ -40,18 +41,20 @@ func NewOptions(p, o string) *Options { } var examples = ` -Use the file somedir/kustomization.yaml to generate a set of api resources: - build somedir +To generate the resources specified in 'someDir/kustomization.yaml', run -Use a url pointing to a remote directory/kustomization.yaml to generate a set of api resources: - build url -The url should follow hashicorp/go-getter URL format described in -https://github.com/hashicorp/go-getter#url-format + kustomize build someDir + +The default argument to 'build' is '.' (the current working directory). + +The argument can be a URL resolving to a directory +with a kustomization.yaml file, e.g. -url examples: - sigs.k8s.io/kustomize//examples/multibases?ref=v1.0.6 - github.com/Liujingfang1/mysql - github.com/Liujingfang1/kustomize//examples/helloWorld?ref=repoUrl2 + kustomize build \ + github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6 + +The URL should be formulated as described at +https://github.com/hashicorp/go-getter#url-format ` // NewCmdBuild creates a new build command. @@ -65,8 +68,8 @@ func NewCmdBuild( pl := plugins.NewLoader(pluginConfig, rf) cmd := &cobra.Command{ - Use: "build [path]", - Short: "Print current configuration per contents of " + pgmconfig.KustomizationFileNames[0], + Use: "build {path}", + Short: "Print configuration per contents of " + pgmconfig.KustomizationFileNames[0], Example: examples, SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -82,10 +85,10 @@ func NewCmdBuild( &o.outputPath, "output", "o", "", "If specified, write the build output to this path.") - loader.AddLoadRestrictionsFlag(cmd.Flags()) - plugins.AddEnablePluginsFlag( + loader.AddFlagLoadRestrictor(cmd.Flags()) + plugins.AddFlagEnablePlugins( cmd.Flags(), &pluginConfig.Enabled) - + addFlagReorderOutput(cmd.Flags()) cmd.AddCommand(NewCmdBuildPrune(out, v, fSys, rf, ptf, pl)) return cmd } @@ -101,7 +104,11 @@ func (o *Options) Validate(args []string) (err error) { } else { o.kustomizationPath = args[0] } - o.loadRestrictor, err = loader.ValidateLoadRestrictorFlag() + o.loadRestrictor, err = loader.ValidateFlagLoadRestrictor() + if err != nil { + return err + } + o.outOrder, err = validateFlagReorderOutput() return } @@ -153,11 +160,13 @@ func (o *Options) emitResources( if o.outputPath != "" && fSys.IsDir(o.outputPath) { return writeIndividualFiles(fSys, o.outputPath, m) } - // Done this way just to prove that overall sorting - // can be performed by a plugin. This particular - // plugin doesn't require configuration; just make - // it and call transform. - builtin.NewPreferredOrderTransformerPlugin().Transform(m) + if o.outOrder == legacy { + // Done this way just to show how overall sorting + // can be performed by a plugin. This particular + // plugin doesn't require configuration; just make + // it and call transform. + builtin.NewLegacyOrderTransformerPlugin().Transform(m) + } res, err := m.AsYaml() if err != nil { return err diff --git a/pkg/commands/build/reorderoutput.go b/pkg/commands/build/reorderoutput.go new file mode 100644 index 0000000000..63ed2ec301 --- /dev/null +++ b/pkg/commands/build/reorderoutput.go @@ -0,0 +1,50 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + + "github.com/spf13/pflag" +) + +//go:generate stringer -type=reorderOutput +type reorderOutput int + +const ( + unspecified reorderOutput = iota + none + legacy +) + +const ( + flagReorderOutputName = "reorder" +) + +var ( + flagReorderOutputValue = legacy.String() + flagReorderOutputHelp = "Reorder the resources just before output. " + + "Use '" + legacy.String() + "' to apply a legacy reordering (Namespaces first, Webhooks last, etc). " + + "Use '" + none.String() + "' to suppress a final reordering." +) + +func addFlagReorderOutput(set *pflag.FlagSet) { + set.StringVar( + &flagReorderOutputValue, flagReorderOutputName, + legacy.String(), flagReorderOutputHelp) +} + +func validateFlagReorderOutput() (reorderOutput, error) { + switch flagReorderOutputValue { + case none.String(): + return none, nil + case legacy.String(): + return legacy, nil + default: + return unspecified, fmt.Errorf( + "illegal flag value --%s %s; legal values: %v", + flagReorderOutputName, flagReorderOutputValue, + []string{legacy.String(), none.String()}) + } +} diff --git a/pkg/commands/build/reorderoutput_string.go b/pkg/commands/build/reorderoutput_string.go new file mode 100644 index 0000000000..1fa60051e9 --- /dev/null +++ b/pkg/commands/build/reorderoutput_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -type=reorderOutput"; DO NOT EDIT. + +package build + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[unspecified-0] + _ = x[none-1] + _ = x[legacy-2] +} + +const _reorderOutput_name = "unspecifiednonelegacy" + +var _reorderOutput_index = [...]uint8{0, 11, 15, 21} + +func (i reorderOutput) String() string { + if i < 0 || i >= reorderOutput(len(_reorderOutput_index)-1) { + return "reorderOutput(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _reorderOutput_name[_reorderOutput_index[i]:_reorderOutput_index[i+1]] +} diff --git a/pkg/kusttest/kusttestharness.go b/pkg/kusttest/kusttestharness.go index af7855caad..8a990482cf 100644 --- a/pkg/kusttest/kusttestharness.go +++ b/pkg/kusttest/kusttestharness.go @@ -186,6 +186,16 @@ func hint(a, b string) string { func (th *KustTestHarness) AssertActualEqualsExpected( m resmap.ResMap, expected string) { + th.assertActualEqualsExpected(m, expected, true) +} + +func (th *KustTestHarness) AssertActualEqualsExpectedNoSort( + m resmap.ResMap, expected string) { + th.assertActualEqualsExpected(m, expected, false) +} + +func (th *KustTestHarness) assertActualEqualsExpected( + m resmap.ResMap, expected string, doLegacySort bool) { if m == nil { th.t.Fatalf("Map should not be nil.") } @@ -194,8 +204,9 @@ func (th *KustTestHarness) AssertActualEqualsExpected( if len(expected) > 0 && expected[0] == 10 { expected = expected[1:] } - // The tests currently expect a particular ordering. - builtin.NewPreferredOrderTransformerPlugin().Transform(m) + if doLegacySort { + builtin.NewLegacyOrderTransformerPlugin().Transform(m) + } actual, err := m.AsYaml() if err != nil { th.t.Fatalf("Unexpected err: %v", err) diff --git a/pkg/loader/loadrestrictions.go b/pkg/loader/loadrestrictions.go index 33fed8d244..a797b3c95c 100644 --- a/pkg/loader/loadrestrictions.go +++ b/pkg/loader/loadrestrictions.go @@ -43,13 +43,13 @@ var ( "This does, however, break the relocatability of the kustomization." ) -func AddLoadRestrictionsFlag(set *pflag.FlagSet) { +func AddFlagLoadRestrictor(set *pflag.FlagSet) { set.StringVar( &flagValue, flagName, rootOnly.String(), flagHelp) } -func ValidateLoadRestrictorFlag() (LoadRestrictorFunc, error) { +func ValidateFlagLoadRestrictor() (LoadRestrictorFunc, error) { switch flagValue { case rootOnly.String(): return RestrictionRootOnly, nil diff --git a/pkg/plugins/config.go b/pkg/plugins/config.go index 2edd2ed341..3100adc321 100644 --- a/pkg/plugins/config.go +++ b/pkg/plugins/config.go @@ -46,7 +46,7 @@ func NotEnabledErr(name string) error { flagEnablePluginsHelp) } -func AddEnablePluginsFlag(set *pflag.FlagSet, v *bool) { +func AddFlagEnablePlugins(set *pflag.FlagSet, v *bool) { set.BoolVar( v, flagEnablePluginsName, false, flagEnablePluginsHelp) diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index c06f9c4a34..52ef8058ef 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -17,14 +17,79 @@ limitations under the License. package target_test import ( - "sigs.k8s.io/kustomize/pkg/plugins" "strings" "testing" "sigs.k8s.io/kustomize/pkg/kusttest" "sigs.k8s.io/kustomize/pkg/loader" + "sigs.k8s.io/kustomize/pkg/plugins" ) +// TODO(monopole): Make prefixsuffixtransformer changes +// needed to enable this test. +func disabledTestOrderPreserved(t *testing.T) { + th := kusttest_test.NewKustTestHarness(t, "/app/prod") + th.WriteK("/app/base", ` +namePrefix: b- +resources: +- namespace.yaml +- role.yaml +- service.yaml +- deployment.yaml +`) + th.WriteF("/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: myService +`) + th.WriteF("/app/base/namespace.yaml", ` +apiVersion: v1 +kind: Namespace +metadata: + name: myNs +`) + th.WriteF("/app/base/role.yaml", ` +apiVersion: v1 +kind: Role +metadata: + name: myRole +`) + th.WriteF("/app/base/deployment.yaml", ` +apiVersion: v1 +kind: Deployment +metadata: + name: myDep +`) + th.WriteK("/app/prod", ` +namePrefix: p- +resources: +- ../base +- service.yaml +- namespace.yaml +`) + th.WriteF("/app/prod/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: myService2 +`) + th.WriteF("/app/prod/namespace.yaml", ` +apiVersion: v1 +kind: Namespace +metadata: + name: myNs2 +`) + + m, err := th.MakeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.AssertActualEqualsExpectedNoSort(m, ` +TBD +./tr `) +} + func TestBaseInResourceList(t *testing.T) { th := kusttest_test.NewKustTestHarness(t, "/app/prod") th.WriteK("/app/prod", ` diff --git a/plugin/builtin/PreferredOrderTransformer.go b/plugin/builtin/LegacyOrderTransformer.go similarity index 68% rename from plugin/builtin/PreferredOrderTransformer.go rename to plugin/builtin/LegacyOrderTransformer.go index d6e783d6f7..6b5c2e586b 100644 --- a/plugin/builtin/PreferredOrderTransformer.go +++ b/plugin/builtin/LegacyOrderTransformer.go @@ -1,4 +1,4 @@ -// Code generated by pluginator on PreferredOrderTransformer; DO NOT EDIT. +// Code generated by pluginator on LegacyOrderTransformer; DO NOT EDIT. package builtin import ( @@ -13,19 +13,19 @@ import ( // dependencies (like Namespace, StorageClass, etc.) // first, and resources with a high number of dependencies // (like ValidatingWebhookConfiguration) last. -type PreferredOrderTransformerPlugin struct{} +type LegacyOrderTransformerPlugin struct{} -func NewPreferredOrderTransformerPlugin() *PreferredOrderTransformerPlugin { - return &PreferredOrderTransformerPlugin{} +func NewLegacyOrderTransformerPlugin() *LegacyOrderTransformerPlugin { + return &LegacyOrderTransformerPlugin{} } // Nothing needed for configuration. -func (p *PreferredOrderTransformerPlugin) Config( +func (p *LegacyOrderTransformerPlugin) Config( ldr ifc.Loader, rf *resmap.Factory, c []byte) (err error) { return nil } -func (p *PreferredOrderTransformerPlugin) Transform(m resmap.ResMap) error { +func (p *LegacyOrderTransformerPlugin) Transform(m resmap.ResMap) error { resources := make([]*resource.Resource, m.Size()) ids := m.AllIds() sort.Sort(resmap.IdSlice(ids)) diff --git a/plugin/builtin/preferredordertransformer/PreferredOrderTransformer.go b/plugin/builtin/legacyordertransformer/LegacyOrderTransformer.go similarity index 100% rename from plugin/builtin/preferredordertransformer/PreferredOrderTransformer.go rename to plugin/builtin/legacyordertransformer/LegacyOrderTransformer.go diff --git a/plugin/builtin/preferredordertransformer/PreferredOrderTransformer_test.go b/plugin/builtin/legacyordertransformer/LegacyOrderTransformer_test.go similarity index 92% rename from plugin/builtin/preferredordertransformer/PreferredOrderTransformer_test.go rename to plugin/builtin/legacyordertransformer/LegacyOrderTransformer_test.go index 96e313cd92..6805376537 100644 --- a/plugin/builtin/preferredordertransformer/PreferredOrderTransformer_test.go +++ b/plugin/builtin/legacyordertransformer/LegacyOrderTransformer_test.go @@ -10,17 +10,17 @@ import ( "sigs.k8s.io/kustomize/plugin" ) -func TestPreferredOrderTransformer(t *testing.T) { +func TestLegacyOrderTransformer(t *testing.T) { tc := plugin.NewEnvForTest(t).Set() defer tc.Reset() tc.BuildGoPlugin( - "builtin", "", "PreferredOrderTransformer") + "builtin", "", "LegacyOrderTransformer") th := kusttest_test.NewKustTestPluginHarness(t, "/app") rm := th.LoadAndRunTransformer(` apiVersion: builtin -kind: PreferredOrderTransformer +kind: LegacyOrderTransformer metadata: name: notImportantHere `, `