diff --git a/Makefile-plugins.mk b/Makefile-plugins.mk index 26efb91c37..2f6ffccc25 100644 --- a/Makefile-plugins.mk +++ b/Makefile-plugins.mk @@ -41,6 +41,7 @@ _builtinplugins = \ PatchTransformer.go \ PrefixTransformer.go \ SuffixTransformer.go \ + ResourceGenerator.go \ ReplacementTransformer.go \ ReplicaCountTransformer.go \ SecretGenerator.go \ @@ -70,6 +71,7 @@ $(pGen)/PatchStrategicMergeTransformer.go: $(pSrc)/patchstrategicmergetransforme $(pGen)/PatchTransformer.go: $(pSrc)/patchtransformer/PatchTransformer.go $(pGen)/PrefixTransformer.go: $(pSrc)/prefixtransformer/PrefixTransformer.go $(pGen)/SuffixTransformer.go: $(pSrc)/suffixtransformer/SuffixTransformer.go +$(pGen)/ResourceGenerator.go: $(pSrc)/resourcegenerator/ResourceGenerator.go $(pGen)/ReplacementTransformer.go: $(pSrc)/replacementtransformer/ReplacementTransformer.go $(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go $(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go diff --git a/api/builtins/builtins.go b/api/builtins/builtins.go index 28649e1129..3a6255f422 100644 --- a/api/builtins/builtins.go +++ b/api/builtins/builtins.go @@ -10,6 +10,7 @@ import ( type ( AnnotationsTransformerPlugin = internal.AnnotationsTransformerPlugin + ResourceGeneratorPlugin = internal.ResourceGeneratorPlugin ConfigMapGeneratorPlugin = internal.ConfigMapGeneratorPlugin HashTransformerPlugin = internal.HashTransformerPlugin HelmChartInflationGeneratorPlugin = internal.HelmChartInflationGeneratorPlugin @@ -28,8 +29,10 @@ type ( ValueAddTransformerPlugin = internal.ValueAddTransformerPlugin ) +//nolint:gochecknoglobals var ( NewAnnotationsTransformerPlugin = internal.NewAnnotationsTransformerPlugin + NewResourceGeneratorPlugin = internal.NewResourceGeneratorPlugin NewConfigMapGeneratorPlugin = internal.NewConfigMapGeneratorPlugin NewHashTransformerPlugin = internal.NewHashTransformerPlugin NewHelmChartInflationGeneratorPlugin = internal.NewHelmChartInflationGeneratorPlugin diff --git a/api/internal/accumulator/resaccumulator.go b/api/internal/accumulator/resaccumulator.go index 0f4008c97f..55a210e5f0 100644 --- a/api/internal/accumulator/resaccumulator.go +++ b/api/internal/accumulator/resaccumulator.go @@ -14,9 +14,8 @@ import ( "sigs.k8s.io/kustomize/kyaml/resid" ) -// ResAccumulator accumulates resources and the rules -// used to customize those resources. It's a ResMap -// plus stuff needed to modify the ResMap. +// ResAccumulator accumulates resources and the rules used to customize those resources. +// It's a ResMap plus stuff needed to modify the ResMap. type ResAccumulator struct { resMap resmap.ResMap tConfig *builtinconfig.TransformerConfig diff --git a/api/internal/builtins/ResourceGenerator.go b/api/internal/builtins/ResourceGenerator.go new file mode 100644 index 0000000000..6aed5096a9 --- /dev/null +++ b/api/internal/builtins/ResourceGenerator.go @@ -0,0 +1,36 @@ +// Code generated by pluginator on ResourceGenerator; DO NOT EDIT. +// pluginator {(devel) unknown } + +package builtins + +import ( + "fmt" + + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +type ResourceGeneratorPlugin struct { + h *resmap.PluginHelpers + Resource string `json:"resource" yaml:"resource"` +} + +func (p *ResourceGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) error { + p.h = h + if err := yaml.Unmarshal(config, p); err != nil { + return fmt.Errorf("failed to unmarshal ResourceGenerator config: %w", err) + } + return nil +} + +func (p *ResourceGeneratorPlugin) Generate() (resmap.ResMap, error) { + resmap, err := p.h.AccumulateResource(p.Resource) + if err != nil { + return nil, fmt.Errorf("failed to Accumulate: %w", err) + } + return resmap, nil +} + +func NewResourceGeneratorPlugin() resmap.GeneratorPlugin { + return &ResourceGeneratorPlugin{} +} diff --git a/api/internal/plugins/builtinhelpers/builtinplugintype_string.go b/api/internal/plugins/builtinhelpers/builtinplugintype_string.go index ddcfcc190c..9e3b355e9e 100644 --- a/api/internal/plugins/builtinhelpers/builtinplugintype_string.go +++ b/api/internal/plugins/builtinhelpers/builtinplugintype_string.go @@ -10,28 +10,29 @@ func _() { var x [1]struct{} _ = x[Unknown-0] _ = x[AnnotationsTransformer-1] - _ = x[ConfigMapGenerator-2] - _ = x[IAMPolicyGenerator-3] - _ = x[HashTransformer-4] - _ = x[ImageTagTransformer-5] - _ = x[LabelTransformer-6] - _ = x[NamespaceTransformer-7] - _ = x[PatchJson6902Transformer-8] - _ = x[PatchStrategicMergeTransformer-9] - _ = x[PatchTransformer-10] - _ = x[PrefixSuffixTransformer-11] - _ = x[PrefixTransformer-12] - _ = x[SuffixTransformer-13] - _ = x[ReplicaCountTransformer-14] - _ = x[SecretGenerator-15] - _ = x[ValueAddTransformer-16] - _ = x[HelmChartInflationGenerator-17] - _ = x[ReplacementTransformer-18] + _ = x[ResourceGenerator-2] + _ = x[ConfigMapGenerator-3] + _ = x[IAMPolicyGenerator-4] + _ = x[HashTransformer-5] + _ = x[ImageTagTransformer-6] + _ = x[LabelTransformer-7] + _ = x[NamespaceTransformer-8] + _ = x[PatchJson6902Transformer-9] + _ = x[PatchStrategicMergeTransformer-10] + _ = x[PatchTransformer-11] + _ = x[PrefixSuffixTransformer-12] + _ = x[PrefixTransformer-13] + _ = x[SuffixTransformer-14] + _ = x[ReplicaCountTransformer-15] + _ = x[SecretGenerator-16] + _ = x[ValueAddTransformer-17] + _ = x[HelmChartInflationGenerator-18] + _ = x[ReplacementTransformer-19] } -const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorIAMPolicyGeneratorHashTransformerImageTagTransformerLabelTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerPrefixTransformerSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer" +const _BuiltinPluginType_name = "UnknownAnnotationsTransformerResourceGeneratorConfigMapGeneratorIAMPolicyGeneratorHashTransformerImageTagTransformerLabelTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerPrefixTransformerSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer" -var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 65, 80, 99, 115, 135, 159, 189, 205, 228, 245, 262, 285, 300, 319, 346, 368} +var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 46, 64, 82, 97, 116, 132, 152, 176, 206, 222, 245, 262, 279, 302, 317, 336, 363, 385} func (i BuiltinPluginType) String() string { if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) { diff --git a/api/internal/plugins/builtinhelpers/builtins.go b/api/internal/plugins/builtinhelpers/builtins.go index a98a23d398..9c00851e93 100644 --- a/api/internal/plugins/builtinhelpers/builtins.go +++ b/api/internal/plugins/builtinhelpers/builtins.go @@ -14,6 +14,7 @@ type BuiltinPluginType int const ( Unknown BuiltinPluginType = iota AnnotationsTransformer + ResourceGenerator ConfigMapGenerator IAMPolicyGenerator HashTransformer @@ -59,6 +60,7 @@ func GetBuiltinPluginType(n string) BuiltinPluginType { } var GeneratorFactories = map[BuiltinPluginType]func() resmap.GeneratorPlugin{ + ResourceGenerator: builtins.NewResourceGeneratorPlugin, ConfigMapGenerator: builtins.NewConfigMapGeneratorPlugin, IAMPolicyGenerator: builtins.NewIAMPolicyGeneratorPlugin, SecretGenerator: builtins.NewSecretGeneratorPlugin, diff --git a/api/internal/plugins/execplugin/execplugin_test.go b/api/internal/plugins/execplugin/execplugin_test.go index 911ab8e7b4..a9fd4c45aa 100644 --- a/api/internal/plugins/execplugin/execplugin_test.go +++ b/api/internal/plugins/execplugin/execplugin_test.go @@ -31,8 +31,7 @@ func TestExecPluginConfig(t *testing.T) { err := fSys.WriteFile("sed-input.txt", []byte(` s/$FOO/foo/g s/$BAR/bar baz/g - \ \ \ -`)) + \ \ \ `)) require.NoError(t, err) ldr, err := fLdr.NewLoader( fLdr.RestrictionRootOnly, filesys.Separator, fSys) @@ -74,8 +73,7 @@ s/$BAR/bar baz/g t.Fatalf("unexpected err: %v", err) } err = p.Config( - resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf, pc), - yaml) + resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf, pc), yaml) require.NoError(t, err) expected := "someteam.example.com/v1/sedtransformer/SedTransformer" diff --git a/api/internal/plugins/loader/loader.go b/api/internal/plugins/loader/loader.go index e494df767e..0bb8ba9658 100644 --- a/api/internal/plugins/loader/loader.go +++ b/api/internal/plugins/loader/loader.go @@ -57,10 +57,10 @@ func (l *Loader) Config() *types.PluginConfig { } func (l *Loader) LoadGenerators( - ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ( + ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap, kt resmap.KustTargetInterface) ( result []*resmap.GeneratorWithProperties, err error) { for _, res := range rm.Resources() { - g, err := l.LoadGenerator(ldr, v, res) + g, err := l.LoadGenerator(ldr, v, res, kt) if err != nil { return nil, fmt.Errorf("failed to load generator: %w", err) } @@ -74,8 +74,8 @@ func (l *Loader) LoadGenerators( } func (l *Loader) LoadGenerator( - ldr ifc.Loader, v ifc.Validator, res *resource.Resource) (resmap.Generator, error) { - c, err := l.loadAndConfigurePlugin(ldr, v, res) + ldr ifc.Loader, v ifc.Validator, res *resource.Resource, kt resmap.KustTargetInterface) (resmap.Generator, error) { + c, err := l.loadAndConfigurePlugin(ldr, v, res, kt) if err != nil { return nil, err } @@ -87,10 +87,10 @@ func (l *Loader) LoadGenerator( } func (l *Loader) LoadTransformers( - ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]*resmap.TransformerWithProperties, error) { + ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap, kt resmap.KustTargetInterface) ([]*resmap.TransformerWithProperties, error) { var result []*resmap.TransformerWithProperties for _, res := range rm.Resources() { - t, err := l.LoadTransformer(ldr, v, res) + t, err := l.LoadTransformer(ldr, v, res, kt) if err != nil { return nil, err } @@ -104,8 +104,8 @@ func (l *Loader) LoadTransformers( } func (l *Loader) LoadTransformer( - ldr ifc.Loader, v ifc.Validator, res *resource.Resource) (*resmap.TransformerWithProperties, error) { - c, err := l.loadAndConfigurePlugin(ldr, v, res) + ldr ifc.Loader, v ifc.Validator, res *resource.Resource, kt resmap.KustTargetInterface) (*resmap.TransformerWithProperties, error) { + c, err := l.loadAndConfigurePlugin(ldr, v, res, kt) if err != nil { return nil, err } @@ -179,7 +179,9 @@ func isBuiltinPlugin(res *resource.Resource) bool { func (l *Loader) loadAndConfigurePlugin( ldr ifc.Loader, v ifc.Validator, - res *resource.Resource) (c resmap.Configurable, err error) { + res *resource.Resource, + kt resmap.KustTargetInterface, +) (c resmap.Configurable, err error) { if isBuiltinPlugin(res) { switch l.pc.BpLoadingOptions { case types.BploLoadFromFileSys: @@ -214,7 +216,7 @@ func (l *Loader) loadAndConfigurePlugin( if err != nil { return nil, errors.WrapPrefixf(err, "marshalling yaml from res %s", res.OrgId()) } - err = c.Config(resmap.NewPluginHelpers(ldr, v, l.rf, l.pc), yaml) + err = c.Config(resmap.NewPluginHelpersWithKt(ldr, v, l.rf, l.pc, kt), yaml) if err != nil { return nil, errors.WrapPrefixf( err, "plugin %s fails configuration", res.OrgId()) @@ -282,4 +284,3 @@ func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, err } return c, nil } - diff --git a/api/internal/plugins/loader/loader_test.go b/api/internal/plugins/loader/loader_test.go index fd95a358c3..9cc2d369b9 100644 --- a/api/internal/plugins/loader/loader_test.go +++ b/api/internal/plugins/loader/loader_test.go @@ -73,7 +73,7 @@ func TestLoader(t *testing.T) { t.Fatal("expect non-nil loader") } _, err = pLdr.LoadGenerators( - fLdr, valtest_test.MakeFakeValidator(), generatorConfigs) + fLdr, valtest_test.MakeFakeValidator(), generatorConfigs, nil) if err != nil { t.Fatal(err) } diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go index 5f1d1095a1..275271085f 100644 --- a/api/internal/target/kusttarget.go +++ b/api/internal/target/kusttarget.go @@ -34,7 +34,7 @@ type KustTarget struct { ldr ifc.Loader validator ifc.Validator rFactory *resmap.Factory - pLdr *loader.Loader + pLdr *loader.Loader // plugin loader origin *resource.Origin } @@ -176,6 +176,15 @@ func (kt *KustTarget) addHashesToNames( return ra.Transform(p) } +// AccumulateResource fills the given resourceAccumulator with resources read from the given path from external package. +func (kt *KustTarget) AccumulateResource(path string) (rm resmap.ResMap, err error) { + ra := accumulator.MakeEmptyAccumulator() + if err := kt.accumulateResource(ra, path); err != nil { + return nil, fmt.Errorf("failed to accumulateResource: %w", err) + } + return ra.ResMap(), nil +} + // AccumulateTarget returns a new ResAccumulator, // holding customized resources and the data/rules used // to do so. The name back references and vars are @@ -196,34 +205,27 @@ func (kt *KustTarget) AccumulateTarget() ( // ra should be empty when this KustTarget is a Kustomization, or the ra of the parent if this KustTarget is a Component // (or empty if the Component does not have a parent). -func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) ( - resRa *accumulator.ResAccumulator, err error) { - ra, err = kt.accumulateResources(ra, kt.kustomization.Resources) - if err != nil { - return nil, errors.WrapPrefixf(err, "accumulating resources") - } +func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (resRa *accumulator.ResAccumulator, err error) { tConfig, err := builtinconfig.MakeTransformerConfig( kt.ldr, kt.kustomization.Configurations) if err != nil { return nil, err } - err = ra.MergeConfig(tConfig) - if err != nil { - return nil, errors.WrapPrefixf( - err, "merging config %v", tConfig) + if err := ra.MergeConfig(tConfig); err != nil { + return nil, errors.WrapPrefixf(err, "merging config %v", tConfig) } + + // load CRDs schemas crdTc, err := accumulator.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds) if err != nil { - return nil, errors.WrapPrefixf( - err, "loading CRDs %v", kt.kustomization.Crds) + return nil, errors.WrapPrefixf(err, "loading CRDs %v", kt.kustomization.Crds) } - err = ra.MergeConfig(crdTc) - if err != nil { - return nil, errors.WrapPrefixf( - err, "merging CRDs %v", crdTc) + if err := ra.MergeConfig(crdTc); err != nil { + return nil, errors.WrapPrefixf(err, "merging CRDs %v", crdTc) } - err = kt.runGenerators(ra) - if err != nil { + + // exec Generators + if err := kt.runGenerators(ra); err != nil { return nil, err } @@ -234,16 +236,19 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) ( return nil, errors.WrapPrefixf(err, "accumulating components") } - err = kt.runTransformers(ra) - if err != nil { + // exec Transformers + if err := kt.runTransformers(ra); err != nil { return nil, err } - err = kt.runValidators(ra) - if err != nil { + + // exec Validators + if err := kt.runValidators(ra); err != nil { return nil, err } - err = ra.MergeVars(kt.kustomization.Vars) - if err != nil { + + // merging `vars` + //nolint:staticcheck + if err := ra.MergeVars(kt.kustomization.Vars); err != nil { return nil, errors.WrapPrefixf( err, "merging vars %v", kt.kustomization.Vars) } @@ -324,7 +329,7 @@ func (kt *KustTarget) configureExternalGenerators() ( if err != nil { return nil, err } - return kt.pLdr.LoadGenerators(kt.ldr, kt.validator, ra.ResMap()) + return kt.pLdr.LoadGenerators(kt.ldr, kt.validator, ra.ResMap(), kt) } func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error { @@ -371,7 +376,7 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]*r if err != nil { return nil, err } - return kt.pLdr.LoadTransformers(kt.ldr, kt.validator, ra.ResMap()) + return kt.pLdr.LoadTransformers(kt.ldr, kt.validator, ra.ResMap(), kt) } func (kt *KustTarget) runValidators(ra *accumulator.ResAccumulator) error { @@ -417,44 +422,56 @@ func (kt *KustTarget) removeValidatedByLabel(rm resmap.ResMap) error { func (kt *KustTarget) accumulateResources( ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) { for _, path := range paths { - // try loading resource as file then as base (directory or git repository) - if errF := kt.accumulateFile(ra, path); errF != nil { - // not much we can do if the error is an HTTP error so we bail out - if errors.Is(errF, load.ErrHTTP) { - return nil, errF - } - ldr, err := kt.ldr.New(path) - if err != nil { - // If accumulateFile found malformed YAML and there was a failure - // loading the resource as a base, then the resource is likely a - // file. The loader failure message is unnecessary, and could be - // confusing. Report only the file load error. - // - // However, a loader timeout implies there is a git repo at the - // path. In that case, both errors could be important. - if kusterr.IsMalformedYAMLError(errF) && !utils.IsErrTimeout(err) { - return nil, errF - } - return nil, errors.WrapPrefixf( - err, "accumulation err='%s'", errF.Error()) - } - // store the origin, we'll need it later - origin := kt.origin.Copy() - if kt.origin != nil { - kt.origin = kt.origin.Append(path) - ra, err = kt.accumulateDirectory(ra, ldr, false) - // after we are done recursing through the directory, reset the origin - kt.origin = &origin - } else { - ra, err = kt.accumulateDirectory(ra, ldr, false) + if err := kt.accumulateResource(ra, path); err != nil { + return nil, err + } + } + return ra, nil +} + +// accumulateResource fills the given resourceAccumulator with resources read from the given path. +func (kt *KustTarget) accumulateResource(ra *accumulator.ResAccumulator, path string) error { + // try loading resource as file then as base (directory or git repository) + if errF := kt.accumulateFile(ra, path); errF != nil { //nolint:nestif + // not much we can do if the error is an HTTP error so we bail out + if errors.Is(errF, load.ErrHTTP) { + return errF + } + ldr, err := kt.ldr.New(path) + if err != nil { + // If accumulateFile found malformed YAML and there was a failure + // loading the resource as a base, then the resource is likely a + // file. The loader failure message is unnecessary, and could be + // confusing. Report only the file load error. + // + // However, a loader timeout implies there is a git repo at the + // path. In that case, both errors could be important. + if kusterr.IsMalformedYAMLError(errF) && !utils.IsErrTimeout(err) { + return errF } - if err != nil { - return nil, errors.WrapPrefixf( - err, "accumulation err='%s'", errF.Error()) + return errors.WrapPrefixf( + err, "accumulation err='%s'", errF.Error()) + } + // store the origin, we'll need it later + origin := kt.origin.Copy() + if kt.origin != nil { + kt.origin = kt.origin.Append(path) + _, err = kt.accumulateDirectory(ra, ldr, false) + // after we are done recursing through the directory, reset the origin + kt.origin = &origin + } else { + _, err = kt.accumulateDirectory(ra, ldr, false) + } + if err != nil { + // Some error occurred while tyring to decode YAML file + if kusterr.IsMalformedYAMLError(errF) { + return errF } + return errors.WrapPrefixf( + err, "accumulation err='%s'", errF.Error()) } } - return ra, nil + return nil } // accumulateComponents fills the given resourceAccumulator @@ -529,8 +546,7 @@ func (kt *KustTarget) accumulateDirectory( return nil, errors.WrapPrefixf( err, "recursed accumulation of path '%s'", ldr.Root()) } - err = ra.MergeAccumulator(subRa) - if err != nil { + if err := ra.MergeAccumulator(subRa); err != nil { return nil, errors.WrapPrefixf( err, "recursed merging from path '%s'", ldr.Root()) } @@ -571,8 +587,8 @@ func (kt *KustTarget) configureBuiltinPlugin( } } err = p.Config( - resmap.NewPluginHelpers( - kt.ldr, kt.validator, kt.rFactory, kt.pLdr.Config()), + resmap.NewPluginHelpersWithKt( + kt.ldr, kt.validator, kt.rFactory, kt.pLdr.Config(), kt), y) if err != nil { return errors.WrapPrefixf( diff --git a/api/internal/target/kusttarget_configplugin.go b/api/internal/target/kusttarget_configplugin.go index 1ba028a36f..0d5acd80a4 100644 --- a/api/internal/target/kusttarget_configplugin.go +++ b/api/internal/target/kusttarget_configplugin.go @@ -34,6 +34,7 @@ import ( func (kt *KustTarget) configureBuiltinGenerators() ( result []*resmap.GeneratorWithProperties, err error) { for _, bpt := range []builtinhelpers.BuiltinPluginType{ + builtinhelpers.ResourceGenerator, builtinhelpers.ConfigMapGenerator, builtinhelpers.SecretGenerator, builtinhelpers.HelmChartInflationGenerator, @@ -66,9 +67,7 @@ func (kt *KustTarget) configureBuiltinGenerators() ( return result, nil } -func (kt *KustTarget) configureBuiltinTransformers( - tc *builtinconfig.TransformerConfig) ( - result []*resmap.TransformerWithProperties, err error) { +func (kt *KustTarget) configureBuiltinTransformers(tc *builtinconfig.TransformerConfig) (result []*resmap.TransformerWithProperties, err error) { for _, bpt := range []builtinhelpers.BuiltinPluginType{ builtinhelpers.PatchStrategicMergeTransformer, builtinhelpers.PatchTransformer, @@ -110,10 +109,32 @@ func (kt *KustTarget) configureBuiltinTransformers( type gFactory func() resmap.GeneratorPlugin +type ResourceArgs struct { + Resource string `json:"resource,omitempty" yaml:"resource,omitempty"` + Kt *KustTarget `json:"kusttarget,omitempty" yaml:"kusttarget,omitempty"` +} + var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, factory gFactory) (result []resmap.Generator, err error){ + builtinhelpers.ResourceGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( + result []resmap.Generator, err error) { + var c struct { + Resource string `json:"resource" yaml:"resource"` + } + for _, args := range kt.kustomization.Resources { + c.Resource = args + p := f() + + if err := kt.configureBuiltinPlugin(p, c, bpt); err != nil { + return nil, err + } + result = append(result, p) + } + return + }, + builtinhelpers.SecretGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( result []resmap.Generator, err error) { var c struct { diff --git a/api/krusty/accumulation_test.go b/api/krusty/accumulation_test.go index a39805786d..98266997d7 100644 --- a/api/krusty/accumulation_test.go +++ b/api/krusty/accumulation_test.go @@ -221,7 +221,7 @@ resources: } buildError := func(tc testcase) string { const ( - prefix = "accumulating resources" + prefix = "failed to accumulateResource" filePrefixf = "accumulating resources from '%s'" fileWrapperIfDirf = "accumulation err='%s'" separator = ": " diff --git a/api/krusty/complexcomposition_test.go b/api/krusty/complexcomposition_test.go index 7c3dfc39fd..553ffc833e 100644 --- a/api/krusty/complexcomposition_test.go +++ b/api/krusty/complexcomposition_test.go @@ -81,7 +81,7 @@ apiVersion: builtin kind: PatchTransformer metadata: name: svcNameTran -target: +target: group: apps version: v1 kind: StatefulSet @@ -153,7 +153,7 @@ apiVersion: builtin kind: PatchTransformer metadata: name: envFromConfigTrans -target: +target: group: apps version: v1 kind: StatefulSet @@ -213,7 +213,7 @@ apiVersion: builtin kind: PatchTransformer metadata: name: tolTrans -target: +target: group: apps version: v1 kind: StatefulSet @@ -264,7 +264,7 @@ apiVersion: builtin kind: PatchTransformer metadata: name: storageTrans -target: +target: group: apps version: v1 kind: StatefulSet @@ -365,10 +365,10 @@ resources: `) err := th.RunWithErr("dev", th.MakeDefaultOptions()) if err == nil { - t.Fatalf("Expected resource accumulation error") + t.Fatalf("Expected resource accumulation error:\n%s\n", th.Run("dev", th.MakeDefaultOptions())) } - if !strings.Contains( - err.Error(), "already registered id: StatefulSet.v1.apps/my-sts.[noNs]") { + if !strings.Contains(err.Error(), + `resid.ResId{Gvk:resid.Gvk{Group:"apps", Version:"v1", Kind:"StatefulSet", isClusterScoped:false}, Name:"my-sts", Namespace:""} exists`) { t.Fatalf("Unexpected err: %v", err) } } @@ -459,7 +459,7 @@ resources: t.Fatalf("Expected resource accumulation error") } if !strings.Contains( - err.Error(), "already registered id: StatefulSet.v1.apps/my-sts.[noNs]") { + err.Error(), `id resid.ResId{Gvk:resid.Gvk{Group:"apps", Version:"v1", Kind:"StatefulSet", isClusterScoped:false}, Name:"my-sts", Namespace:""} exists`) { t.Fatalf("Unexpected err: %v", err) } } diff --git a/api/krusty/component_test.go b/api/krusty/component_test.go index f0965d923a..db6b7e3136 100644 --- a/api/krusty/component_test.go +++ b/api/krusty/component_test.go @@ -380,7 +380,8 @@ spec: `, }, // See how nameSuffix "-b" is also added to the resources included by "comp-a" because they are in the - // accumulator when "comp-b" is accumulated. In practice we could use simple Kustomizations for this example. + // accumulator when "comp-b" is accumulated. + // In practice we could use simple Kustomizations for this example. "components-can-add-the-same-base-if-the-first-renames-resources": { input: []FileGen{writeTestBase, deployment("proxy", "comp-a/proxy.yaml"), @@ -391,9 +392,6 @@ resources: nameSuffix: "-a" `), writeC("comp-b", ` -resources: -- ../base - nameSuffix: "-b" `), writeK("prod", ` @@ -417,21 +415,6 @@ data: kind: ConfigMap metadata: name: my-configmap-a-b-9cd648hm8f ---- -apiVersion: v1 -kind: Deployment -metadata: - name: storefront-b -spec: - replicas: 1 ---- -apiVersion: v1 -data: - otherValue: green - testValue: purple -kind: ConfigMap -metadata: - name: my-configmap-b-9cd648hm8f `, }, @@ -590,7 +573,7 @@ components: - ../comp-b`), }, runPath: "prod", - expectedError: "may not add resource with an already registered id: Deployment.v1.[noGrp]/proxy.[noNs]", + expectedError: `id resid.ResId{Gvk:resid.Gvk{Group:\"\", Version:\"v1\", Kind:\"Deployment\", isClusterScoped:false}, Name:\"proxy\", Namespace:\"\"} exists`, }, "components-cannot-add-the-same-base": { input: []FileGen{writeTestBase, @@ -609,7 +592,7 @@ components: - ../comp-b`), }, runPath: "prod", - expectedError: "may not add resource with an already registered id: Deployment.v1.[noGrp]/storefront.[noNs]", + expectedError: `resid.ResId{Gvk:resid.Gvk{Group:\"\", Version:\"v1\", Kind:\"Deployment\", isClusterScoped:false}, Name:\"storefront\", Namespace:\"\"} exists`, }, "components-cannot-add-bases-containing-the-same-resource": { input: []FileGen{writeTestBase, @@ -640,7 +623,7 @@ components: - ../comp-b`), }, runPath: "prod", - expectedError: "may not add resource with an already registered id: Deployment.v1.[noGrp]/proxy.[noNs]", + expectedError: `resid.ResId{Gvk:resid.Gvk{Group:\"\", Version:\"v1\", Kind:\"Deployment\", isClusterScoped:false}, Name:\"proxy\", Namespace:\"\"} exists`, }, } diff --git a/api/krusty/remoteloader_test.go b/api/krusty/remoteloader_test.go index 8c96b6a2f9..a297502cd8 100644 --- a/api/krusty/remoteloader_test.go +++ b/api/krusty/remoteloader_test.go @@ -105,7 +105,7 @@ cp -r $ROOT/simple.git/. $ROOT/$HASH_DIR git commit -m "relative submodule" git checkout main git submodule add $ROOT/simple.git submodule - git commit -m "submodule" + git commit -m "submodule" ) `, root, hashDir)) return testRepos{ @@ -176,7 +176,7 @@ resources: { name: "has ref", kustomization: ` -resources: +resources: - "file://$ROOT/simple.git?ref=change-image" `, @@ -383,7 +383,7 @@ resources: resources: - https://github.com/thisisa404.yaml `, - err: "accumulating resources: accumulating resources from 'https://github.com/thisisa404.yaml': HTTP Error: status code 404 (Not Found)", + err: `accumulating resources from 'https://github.com/thisisa404.yaml': HTTP Error: status code 404 (Not Found)`, errT: loader.ErrHTTP, }, } diff --git a/api/resmap/factory.go b/api/resmap/factory.go index 9cc860749c..5ca9e2f60d 100644 --- a/api/resmap/factory.go +++ b/api/resmap/factory.go @@ -28,10 +28,6 @@ func (rmF *Factory) RF() *resource.Factory { return rmF.resF } -func New() ResMap { - return newOne() -} - // FromResource returns a ResMap with one entry. func (rmF *Factory) FromResource(res *resource.Resource) ResMap { m, err := newResMapFromResourceSlice([]*resource.Resource{res}) @@ -123,8 +119,7 @@ func (rmF *Factory) FromSecretArgs( return rmF.FromResource(res), nil } -func newResMapFromResourceSlice( - resources []*resource.Resource) (ResMap, error) { +func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) { result := New() for _, res := range resources { err := result.Append(res) diff --git a/api/resmap/resmap.go b/api/resmap/resmap.go index ea913ba6ba..101cf32650 100644 --- a/api/resmap/resmap.go +++ b/api/resmap/resmap.go @@ -6,6 +6,8 @@ package resmap import ( + "fmt" + "sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/types" @@ -49,9 +51,16 @@ type Configurable interface { // NewPluginHelpers makes an instance of PluginHelpers. func NewPluginHelpers( - ldr ifc.Loader, v ifc.Validator, rf *Factory, - pc *types.PluginConfig) *PluginHelpers { - return &PluginHelpers{ldr: ldr, v: v, rf: rf, pc: pc} + ldr ifc.Loader, v ifc.Validator, rf *Factory, pc *types.PluginConfig, +) *PluginHelpers { + return &PluginHelpers{ldr: ldr, v: v, rf: rf, pc: pc, kt: nil} // TODO(koba1t): check to influence of kt is null +} + +// NewPluginHelpersWithKt makes an instance of PluginHelpers additional kt with args. +func NewPluginHelpersWithKt( + ldr ifc.Loader, v ifc.Validator, rf *Factory, pc *types.PluginConfig, kt KustTargetInterface, +) *PluginHelpers { + return &PluginHelpers{ldr: ldr, v: v, rf: rf, pc: pc, kt: kt} } // PluginHelpers holds things that any or all plugins might need. @@ -62,6 +71,21 @@ type PluginHelpers struct { v ifc.Validator rf *Factory pc *types.PluginConfig + kt KustTargetInterface +} + +// KustTargetInterface is the interface for exec accumulate functions from external packages. +type KustTargetInterface interface { + AccumulateResource(path string) (ResMap, error) +} + +// AccumulateResources exec target.(*KustTarget).AccumulateResource() +func (c *PluginHelpers) AccumulateResource(path string) (ResMap, error) { + resmap, err := c.kt.AccumulateResource(path) + if err != nil { + return nil, fmt.Errorf("failed to AccumulateResource in internal 'target' pkg: %w", err) + } + return resmap, nil } func (c *PluginHelpers) GeneralConfig() *types.PluginConfig { diff --git a/api/resmap/reswrangler.go b/api/resmap/reswrangler.go index 2e34fae6a7..8d25c89775 100644 --- a/api/resmap/reswrangler.go +++ b/api/resmap/reswrangler.go @@ -17,6 +17,16 @@ import ( kyaml "sigs.k8s.io/kustomize/kyaml/yaml" ) +func New() ResMap { + return newOne() +} + +func newOne() *resWrangler { + result := &resWrangler{} + result.Clear() + return result +} + // resWrangler implements ResMap. type resWrangler struct { // Resource list maintained in load (append) order. @@ -26,12 +36,15 @@ type resWrangler struct { // specify in kustomizations to be maintained and // available as an option for final YAML rendering. rList []*resource.Resource + crds []string + vars []types.Var } -func newOne() *resWrangler { - result := &resWrangler{} - result.Clear() - return result +// Clear implements ResMap. +func (m *resWrangler) WithProperties(crds []string, vars []types.Var) ResMap { + m.crds = crds + m.vars = vars + return m } // Clear implements ResMap. diff --git a/api/testutils/kusttest/harnessenhanced.go b/api/testutils/kusttest/harnessenhanced.go index 45273208ac..f82789bd69 100644 --- a/api/testutils/kusttest/harnessenhanced.go +++ b/api/testutils/kusttest/harnessenhanced.go @@ -80,11 +80,12 @@ func makeBaseEnhancedHarness(t *testing.T) *HarnessEnhanced { pte: newPluginTestEnv(t).set(), rf: rf, pl: pLdr.NewLoader( - types.EnabledPluginConfig(types.BploLoadFromFileSys), - rf, + types.EnabledPluginConfig(types.BploLoadFromFileSys), rf, // Plugin configs are always located on disk, // regardless of the test harness's FS - filesys.MakeFsOnDisk())} + filesys.MakeFsOnDisk(), + ), + } } func (th *HarnessEnhanced) ErrIfNoHelm() error { diff --git a/api/types/kustomization.go b/api/types/kustomization.go index 6caa296644..d90004e55d 100644 --- a/api/types/kustomization.go +++ b/api/types/kustomization.go @@ -182,6 +182,8 @@ type Kustomization struct { BuildMetadata []string `json:"buildMetadata,omitempty" yaml:"buildMetadata,omitempty"` } +type FilePath string + const ( deprecatedWarningToRunEditFix = "Run 'kustomize edit fix' to update your Kustomization automatically." deprecatedWarningToRunEditFixExperimential = "[EXPERIMENTAL] Run 'kustomize edit fix' to update your Kustomization automatically." diff --git a/cmd/pluginator/internal/krmfunction/funcwrappersrc/go.mod.src b/cmd/pluginator/internal/krmfunction/funcwrappersrc/go.mod.src index cd9107117a..b5ae160f37 100644 --- a/cmd/pluginator/internal/krmfunction/funcwrappersrc/go.mod.src +++ b/cmd/pluginator/internal/krmfunction/funcwrappersrc/go.mod.src @@ -4,7 +4,7 @@ go 1.22.7 require ( github.com/spf13/cobra v1.4.0 - sigs.k8s.io/kustomize/api v0.12.1 - sigs.k8s.io/kustomize/kyaml v0.13.9 + sigs.k8s.io/kustomize/api v0.14.0 + sigs.k8s.io/kustomize/kyaml v0.14.3 sigs.k8s.io/yaml v1.2.0 ) diff --git a/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go b/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go index ad287238a0..6c2e472f78 100644 --- a/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go +++ b/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go @@ -15,13 +15,12 @@ import ( "sigs.k8s.io/kustomize/kyaml/fn/framework" ) -//nolint func main() { var plugin resmap.Configurable p := provider.NewDefaultDepProvider() resmapFactory := resmap.NewFactory(p.GetResourceFactory()) pluginHelpers := resmap.NewPluginHelpers( - nil, p.GetFieldValidator(), resmapFactory, types.DisabledPluginConfig()) + nil, p.GetFieldValidator(), resmapFactory, types.DisabledPluginConfig()) // TODO(koba1t): check to influence of kt is null processor := framework.ResourceListProcessorFunc(func(resourceList *framework.ResourceList) error { resMap, err := resmapFactory.NewResMapFromRNodeSlice(resourceList.Items) diff --git a/go.work b/go.work index c17bd0af38..5f02bd385c 100644 --- a/go.work +++ b/go.work @@ -35,6 +35,7 @@ use ( ./plugin/builtin/prefixtransformer ./plugin/builtin/replacementtransformer ./plugin/builtin/replicacounttransformer + ./plugin/builtin/resourcegenerator ./plugin/builtin/secretgenerator ./plugin/builtin/sortordertransformer ./plugin/builtin/suffixtransformer diff --git a/go.work.sum b/go.work.sum index 14bb1772e2..9376ff868a 100644 --- a/go.work.sum +++ b/go.work.sum @@ -416,6 +416,7 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= @@ -783,6 +784,7 @@ golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= @@ -799,10 +801,10 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -846,7 +848,6 @@ google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= @@ -882,3 +883,4 @@ rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= diff --git a/hack/generateBuiltinKrmFunctions.sh b/hack/generateBuiltinKrmFunctions.sh index 4c12604f73..08c2bb6b40 100755 --- a/hack/generateBuiltinKrmFunctions.sh +++ b/hack/generateBuiltinKrmFunctions.sh @@ -15,6 +15,7 @@ builtinPlugins=(AnnotationsTransformer \ PrefixSuffixTransformer \ PrefixTransformer \ SuffixTransformer \ + ResourceGenerator \ ReplicaCountTransformer \ SecretGenerator \ ValueAddTransformer \ @@ -29,14 +30,14 @@ fi # Install pluginator -pushd ../cmd/pluginator +pushd ../cmd/pluginator || exit make install -popd +popd || exit for pluginName in ${builtinPlugins[@]}; do - dirName=$(echo $pluginName | tr '[:upper:]' '[:lower:]') + dirName=$(echo "$pluginName" | tr '[:upper:]' '[:lower:]') srcPath="$builtinPluginDir/$dirName/$pluginName.go" dstPath="$KRM_FUNCTION_DIR/$dirName" - pluginator krm -i $srcPath -o $dstPath + pluginator krm -i "$srcPath" -o "$dstPath" done diff --git a/plugin/builtin/resourcegenerator/Makefile b/plugin/builtin/resourcegenerator/Makefile new file mode 120000 index 0000000000..82eab92e26 --- /dev/null +++ b/plugin/builtin/resourcegenerator/Makefile @@ -0,0 +1 @@ +../../../Makefile-modules.mk \ No newline at end of file diff --git a/plugin/builtin/resourcegenerator/ResourceGenerator.go b/plugin/builtin/resourcegenerator/ResourceGenerator.go new file mode 100644 index 0000000000..fb38de23c4 --- /dev/null +++ b/plugin/builtin/resourcegenerator/ResourceGenerator.go @@ -0,0 +1,35 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +//go:generate pluginator +package main + +import ( + "fmt" + + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +type plugin struct { + h *resmap.PluginHelpers + Resource string `json:"resource" yaml:"resource"` +} + +var KustomizePlugin plugin //nolint:gochecknoglobals + +func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) error { + p.h = h + if err := yaml.Unmarshal(config, p); err != nil { + return fmt.Errorf("failed to unmarshal ResourceGenerator config: %w", err) + } + return nil +} + +func (p *plugin) Generate() (resmap.ResMap, error) { + resmap, err := p.h.AccumulateResource(p.Resource) + if err != nil { + return nil, fmt.Errorf("failed to Accumulate: %w", err) + } + return resmap, nil +} diff --git a/plugin/builtin/resourcegenerator/ResourceGenerator_test.go b/plugin/builtin/resourcegenerator/ResourceGenerator_test.go new file mode 100644 index 0000000000..c6d4346fa0 --- /dev/null +++ b/plugin/builtin/resourcegenerator/ResourceGenerator_test.go @@ -0,0 +1,43 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "testing" + + kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" +) + +func TestResourceGenerator(t *testing.T) { + th := kusttest_test.MakeEnhancedHarness(t). + PrepBuiltin("ResourceGenerator") + defer th.Reset() + + th.WriteF("config.yaml", ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: myMap +data: + COLOR: red + FRUIT: apple +`) + rm := th.LoadAndRunGenerator(` +apiVersion: builtin +kind: ResourceGenerator +metadata: + name: myMap +resource: config.yaml +`) + + th.AssertActualEqualsExpected(rm, ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: myMap +data: + COLOR: red + FRUIT: apple +`) +} diff --git a/plugin/builtin/resourcegenerator/go.mod b/plugin/builtin/resourcegenerator/go.mod new file mode 100644 index 0000000000..797a97f160 --- /dev/null +++ b/plugin/builtin/resourcegenerator/go.mod @@ -0,0 +1,42 @@ +module sigs.k8s.io/kustomize/plugin/builtin/resourcegenerator + +go 1.20 + +require sigs.k8s.io/kustomize/api v0.13.4 + +require ( + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.8.1 // indirect + go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/xlab/treeprint v1.2.0 // indirect + golang.org/x/sys v0.8.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3 + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace sigs.k8s.io/kustomize/api => ../../../api + +replace sigs.k8s.io/kustomize/kyaml => ../../../kyaml diff --git a/plugin/builtin/resourcegenerator/go.sum b/plugin/builtin/resourcegenerator/go.sum new file mode 100644 index 0000000000..f63a61abf0 --- /dev/null +++ b/plugin/builtin/resourcegenerator/go.sum @@ -0,0 +1,83 @@ +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961 h1:pqRVJGQJz6oeZby8qmPKXYIBjyrcv7EHCe/33UkZMYA= +k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961/go.mod h1:l8HTwL5fqnlns4jOveW1L75eo7R9KFHxiE0bsPGy428= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=