diff --git a/api/export/target.go b/api/export/target.go new file mode 100644 index 00000000000..f6eccd086d4 --- /dev/null +++ b/api/export/target.go @@ -0,0 +1,33 @@ +package export + +import ( + "fmt" + + "sigs.k8s.io/kustomize/api/internal/accumulator" + "sigs.k8s.io/kustomize/api/internal/target" + "sigs.k8s.io/kustomize/api/resmap" +) + +type KustTarget target.KustTarget + +func (kt *KustTarget) AccumulateTarget() (*accumulator.ResAccumulator, error) { + internalKt := (*target.KustTarget)(kt) + ra, err := internalKt.AccumulateTarget() + if err != nil { + return nil, fmt.Errorf("%w", err) + } + return ra, nil +} + +func (kt *KustTarget) Accumulate() (resmap.ResMap, error) { + internalKt := (*target.KustTarget)(kt) + _, err := internalKt.AccumulateTarget() + if err != nil { + return nil, fmt.Errorf("%w", err) + } + resmap, err := internalKt.MakeCustomizedResMap() + if err != nil { + return nil, fmt.Errorf("%w", err) + } + return resmap, nil +} diff --git a/api/internal/accumulator/resaccumulator.go b/api/internal/accumulator/resaccumulator.go index 0f4008c97ff..55a210e5f07 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 index 61c723cc8d3..6aed5096a93 100644 --- a/api/internal/builtins/ResourceGenerator.go +++ b/api/internal/builtins/ResourceGenerator.go @@ -4,23 +4,31 @@ package builtins import ( + "fmt" + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/kyaml/yaml" ) type ResourceGeneratorPlugin struct { h *resmap.PluginHelpers - resource string + Resource string `json:"resource" yaml:"resource"` } -func (p *ResourceGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { +func (p *ResourceGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) error { p.h = h - return + 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) { - - resourceBytes := []byte(p.resource) //idiot - return p.h.ResmapFactory().NewResMapFromBytes(resourceBytes) + 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 { diff --git a/api/internal/plugins/execplugin/execplugin_test.go b/api/internal/plugins/execplugin/execplugin_test.go index b20626297e3..53cfbee4973 100644 --- a/api/internal/plugins/execplugin/execplugin_test.go +++ b/api/internal/plugins/execplugin/execplugin_test.go @@ -25,7 +25,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( @@ -65,7 +65,7 @@ s/$BAR/bar baz/g t.Fatalf("unexpected err: %v", err) } err = p.Config( - resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf, pc), + resmap.NewPluginHelpers(ldr, pvd.GetFieldValidator(), rf, pc, nil), //TODO yaml) require.NoError(t, err) diff --git a/api/internal/plugins/loader/loader.go b/api/internal/plugins/loader/loader.go index 1758e5cf661..e8cc93dc63e 100644 --- a/api/internal/plugins/loader/loader.go +++ b/api/internal/plugins/loader/loader.go @@ -218,7 +218,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.NewPluginHelpers(ldr, v, l.rf, l.pc, nil), yaml) //TODO if err != nil { return nil, errors.WrapPrefixf( err, "plugin %s fails configuration", res.OrgId()) diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go index 64fb74fc116..79b5cfca6a8 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 @@ -197,11 +206,6 @@ 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) { - // read `resources` - ra, err = kt.accumulateResources(ra, kt.kustomization.Resources) // it needs to remove - if err != nil { - return nil, errors.WrapPrefixf(err, "accumulating resources") - } tConfig, err := builtinconfig.MakeTransformerConfig( kt.ldr, kt.kustomization.Configurations) @@ -419,40 +423,51 @@ 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 kusterr.IsMalformedYAMLError(errF) { // Some error occurred while tyring to decode YAML file - 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 { + // 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 { + // Some error occurred while tyring to decode YAML file + if kusterr.IsMalformedYAMLError(errF) { + + return errF } - if err != nil { - if kusterr.IsMalformedYAMLError(errF) { // Some error occurred while tyring to decode YAML file - return nil, errF - } - 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) + 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 != 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 } // accumulateResources fills the given resourceAccumulator @@ -570,7 +585,7 @@ func (kt *KustTarget) configureBuiltinPlugin( } err = p.Config( resmap.NewPluginHelpers( - kt.ldr, kt.validator, kt.rFactory, kt.pLdr.Config()), + 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 859f1e1ef1d..d47aed26474 100644 --- a/api/internal/target/kusttarget_configplugin.go +++ b/api/internal/target/kusttarget_configplugin.go @@ -109,6 +109,11 @@ func (kt *KustTarget) configureBuiltinTransformers(tc *builtinconfig.Transformer 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, @@ -116,11 +121,12 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.ResourceGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( result []resmap.Generator, err error) { var c struct { - resource string + Resource string `json:"resource" yaml:"resource"` } for _, args := range kt.kustomization.Resources { - c.resource = args + c.Resource = args p := f() + if err := kt.configureBuiltinPlugin(p, c, bpt); err != nil { return nil, err } diff --git a/api/resmap/factory.go b/api/resmap/factory.go index 9cc860749ce..f4e4b9ec80a 100644 --- a/api/resmap/factory.go +++ b/api/resmap/factory.go @@ -143,3 +143,7 @@ func (rmF *Factory) NewResMapFromRNodeSlice(s []*yaml.RNode) (ResMap, error) { } return newResMapFromResourceSlice(rs) } + +// func (rmF *Factory) FromResourceEntry(loader ifc.Loader, resource string, ktInterface interface{}) (ResMap, error) { +// return nil, nil +// } diff --git a/api/resmap/resmap.go b/api/resmap/resmap.go index ea913ba6ba3..2392f360c46 100644 --- a/api/resmap/resmap.go +++ b/api/resmap/resmap.go @@ -49,9 +49,9 @@ 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, 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 +62,17 @@ 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) { + return c.kt.AccumulateResource(path) } func (c *PluginHelpers) GeneralConfig() *types.PluginConfig { diff --git a/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go b/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go index ad287238a0b..65d951d76bf 100644 --- a/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go +++ b/cmd/pluginator/internal/krmfunction/funcwrappersrc/main.go @@ -15,13 +15,13 @@ import ( "sigs.k8s.io/kustomize/kyaml/fn/framework" ) -//nolint +// 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(), nil) //TODO processor := framework.ResourceListProcessorFunc(func(resourceList *framework.ResourceList) error { resMap, err := resmapFactory.NewResMapFromRNodeSlice(resourceList.Items) diff --git a/plugin/builtin/resourcegenerator/ResourceGenerator.go b/plugin/builtin/resourcegenerator/ResourceGenerator.go index ba2c4b3f376..74228c4f629 100644 --- a/plugin/builtin/resourcegenerator/ResourceGenerator.go +++ b/plugin/builtin/resourcegenerator/ResourceGenerator.go @@ -5,23 +5,29 @@ package main import ( + "fmt" + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/kyaml/yaml" ) type plugin struct { h *resmap.PluginHelpers - resource string + Resource string `json:"resource" yaml:"resource"` } -var KustomizePlugin plugin //nolint:gochecknoglobals - -func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { +func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) error { p.h = h - return + 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) { - - resourceBytes := []byte(p.resource) //idiot - return p.h.ResmapFactory().NewResMapFromBytes(resourceBytes) + 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 index 13c5146813d..06b1c146de5 100644 --- a/plugin/builtin/resourcegenerator/ResourceGenerator_test.go +++ b/plugin/builtin/resourcegenerator/ResourceGenerator_test.go @@ -3,9 +3,35 @@ package main_test -import ( - "testing" -) +// func TestResourceGenerator(t *testing.T) { +// th := kusttest_test.MakeEnhancedHarness(t). +// PrepBuiltin("ResourceGenerator") +// defer th.Reset() -func TestResourceGenerator(t *testing.T) { -} +// 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 index bc5c204fdbe..eb909b222a6 100644 --- a/plugin/builtin/resourcegenerator/go.mod +++ b/plugin/builtin/resourcegenerator/go.mod @@ -23,7 +23,7 @@ require ( 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.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.2 sigs.k8s.io/yaml v1.3.0 // indirect )