Merge pull request #3590 from monopole/morePublicSutff

Make more high level build methods public.
This commit is contained in:
Jeff Regan
2021-02-12 11:21:37 -08:00
committed by GitHub
12 changed files with 152 additions and 130 deletions

View File

@@ -19,22 +19,21 @@ import (
"sigs.k8s.io/kustomize/kyaml/openapi"
)
// Kustomizer performs kustomizations. It's meant to behave
// similarly to the kustomize CLI, and can be used instead of
// performing an exec to a kustomize CLI subprocess.
// Kustomizer performs kustomizations.
//
// It's meant to behave similarly to the kustomize CLI, and can be
// used instead of performing an exec to a kustomize CLI subprocess.
// To use, load a filesystem with kustomization files (any
// number of overlays and bases), then make a Kustomizer
// injected with the given fileystem, then call Run.
type Kustomizer struct {
fSys filesys.FileSystem
options *Options
depProvider *provider.DepProvider
}
// MakeKustomizer returns an instance of Kustomizer.
func MakeKustomizer(fSys filesys.FileSystem, o *Options) *Kustomizer {
func MakeKustomizer(o *Options) *Kustomizer {
return &Kustomizer{
fSys: fSys,
options: o,
depProvider: provider.NewDepProvider(o.UseKyaml),
}
@@ -42,16 +41,16 @@ func MakeKustomizer(fSys filesys.FileSystem, o *Options) *Kustomizer {
// Run performs a kustomization.
//
// It uses its internal filesystem reference to read the file at
// the given path argument, interpret it as a kustomization.yaml
// file, perform the kustomization it represents, and return the
// resulting resources.
// It reads given path from the given file system, interprets it as
// a kustomization.yaml file, perform the kustomization it represents,
// and return the resulting resources.
//
// Any files referenced by the kustomization must be present in the
// internal filesystem. One may call Run any number of times,
// on any number of internal paths (e.g. the filesystem may contain
// multiple overlays, and Run can be called on each of them).
func (b *Kustomizer) Run(path string) (resmap.ResMap, error) {
// Any files referenced by the kustomization must be present on the
// filesystem. One may call Run any number of times, on any number
// of internal paths (e.g. the filesystem may contain multiple overlays,
// and Run can be called on each of them).
func (b *Kustomizer) Run(
fSys filesys.FileSystem, path string) (resmap.ResMap, error) {
resmapFactory := resmap.NewFactory(
b.depProvider.GetResourceFactory(),
b.depProvider.GetConflictDetectorFactory())
@@ -59,7 +58,7 @@ func (b *Kustomizer) Run(path string) (resmap.ResMap, error) {
if b.options.LoadRestrictions == types.LoadRestrictionsRootOnly {
lr = fLdr.RestrictionRootOnly
}
ldr, err := fLdr.NewLoader(lr, path, b.fSys)
ldr, err := fLdr.NewLoader(lr, path, fSys)
if err != nil {
return nil, err
}

View File

@@ -16,9 +16,8 @@ import (
// For more substantial tests and examples,
// see other tests in this package.
func TestEmptyFileSystem(t *testing.T) {
fSys := filesys.MakeFsInMemory()
b := krusty.MakeKustomizer(fSys, krusty.MakeDefaultOptions())
_, err := b.Run("noSuchThing")
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
_, err := b.Run(filesys.MakeFsInMemory(), "noSuchThing")
if err == nil {
t.Fatalf("expected error")
}

View File

@@ -14,8 +14,9 @@ import (
func TestRemoteLoad(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(fSys, krusty.MakeDefaultOptions())
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
m, err := b.Run(
fSys,
"github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6")
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.

View File

@@ -93,7 +93,7 @@ func (th Harness) MakeOptionsPluginsEnabled() krusty.Options {
// Run, failing on error.
func (th Harness) Run(path string, o krusty.Options) resmap.ResMap {
m, err := krusty.MakeKustomizer(th.fSys, &o).Run(path)
m, err := krusty.MakeKustomizer(&o).Run(th.fSys, path)
if err != nil {
th.t.Fatal(err)
}
@@ -102,7 +102,7 @@ func (th Harness) Run(path string, o krusty.Options) resmap.ResMap {
// Run, failing if there is no error.
func (th Harness) RunWithErr(path string, o krusty.Options) error {
_, err := krusty.MakeKustomizer(th.fSys, &o).Run(path)
_, err := krusty.MakeKustomizer(&o).Run(th.fSys, path)
if err == nil {
th.t.Fatalf("expected error")
}

View File

@@ -7,18 +7,13 @@ import (
"fmt"
"io"
"log"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
// Options contain the options for running a build
@@ -78,11 +73,31 @@ func NewCmdBuild(help Help, out io.Writer) *cobra.Command {
Example: help.Example,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
if err := o.Validate(args); err != nil {
return err
}
k := krusty.MakeKustomizer(
o.ModifyKrustyOptions(krusty.MakeDefaultOptions()),
)
fSys := filesys.MakeFsOnDisk()
m, err := k.Run(fSys, o.kustomizationPath)
if err != nil {
return err
}
return o.RunBuild(out)
if o.outputPath != "" && fSys.IsDir(o.outputPath) {
// Ignore io.Writer; write to o.outputPath directly.
return MakeWriter(fSys).WriteIndividualFiles(o.outputPath, m)
}
yml, err := m.AsYaml()
if err != nil {
return err
}
if o.outputPath != "" {
// Ignore io.Writer; write to o.outputPath directly.
return fSys.WriteFile(o.outputPath, yml)
}
_, err = out.Write(yml)
return err
},
}
@@ -90,30 +105,13 @@ func NewCmdBuild(help Help, out io.Writer) *cobra.Command {
&o.outputPath,
"output", "o", "",
"If specified, write output to this path.")
cmd.Flags().BoolVar(
&o.fnOptions.EnableExec, "enable-exec", false, /*do not change!*/
"enable support for exec functions -- note: exec functions run arbitrary code -- do not use for untrusted configs!!! (Alpha)")
cmd.Flags().BoolVar(
&o.fnOptions.EnableStar, "enable-star", false,
"enable support for starlark functions. (Alpha)")
cmd.Flags().BoolVar(
&o.fnOptions.Network, "network", false,
"enable network access for functions that declare it")
cmd.Flags().StringVar(
&o.fnOptions.NetworkName, "network-name", "bridge",
"the docker network to run the container in")
cmd.Flags().StringArrayVar(
&o.fnOptions.Mounts, "mount", []string{},
"a list of storage options read from the filesystem")
cmd.Flags().StringArrayVarP(
&o.fnOptions.Env, "env", "e", []string{},
"a list of environment variables to be used by functions")
addFlagLoadRestrictor(cmd.Flags())
addFlagEnablePlugins(cmd.Flags())
addFlagReorderOutput(cmd.Flags())
addFlagEnableManagedbyLabel(cmd.Flags())
addFlagAllowResourceIdChanges(cmd.Flags())
AddFunctionFlags(cmd.Flags(), &o.fnOptions)
AddFlagLoadRestrictor(cmd.Flags())
AddFlagEnablePlugins(cmd.Flags())
AddFlagReorderOutput(cmd.Flags())
AddFlagEnableManagedbyLabel(cmd.Flags())
AddFlagAllowResourceIdChanges(cmd.Flags())
return cmd
}
@@ -138,84 +136,20 @@ func (o *Options) Validate(args []string) (err error) {
return
}
func (o *Options) makeOptions() *krusty.Options {
opts := krusty.MakeDefaultOptions()
opts.DoLegacyResourceSort = o.outOrder == legacy
opts.LoadRestrictions = getFlagLoadRestrictorValue()
// ModifyKrustyOptions feeds command line data into the krusty options.
func (o *Options) ModifyKrustyOptions(kOpts *krusty.Options) *krusty.Options {
kOpts.DoLegacyResourceSort = o.outOrder == legacy
kOpts.LoadRestrictions = getFlagLoadRestrictorValue()
if isFlagEnablePluginsSet() {
c, err := konfig.EnabledPluginConfig(types.BploUseStaticallyLinked)
if err != nil {
log.Fatal(err)
}
c.FnpLoadingOptions = o.fnOptions
opts.PluginConfig = c
kOpts.PluginConfig = c
}
opts.AddManagedbyLabel = isManagedbyLabelEnabled()
opts.UseKyaml = konfig.FlagEnableKyamlDefaultValue
opts.AllowResourceIdChanges = flagAllowResourceIdChangesValue
return opts
}
func (o *Options) RunBuild(out io.Writer) error {
fSys := filesys.MakeFsOnDisk()
k := krusty.MakeKustomizer(fSys, o.makeOptions())
m, err := k.Run(o.kustomizationPath)
if err != nil {
return err
}
return o.emitResources(out, fSys, m)
}
func (o *Options) emitResources(
out io.Writer, fSys filesys.FileSystem, m resmap.ResMap) error {
if o.outputPath != "" && fSys.IsDir(o.outputPath) {
return writeIndividualFiles(fSys, o.outputPath, m)
}
res, err := m.AsYaml()
if err != nil {
return err
}
if o.outputPath != "" {
return fSys.WriteFile(o.outputPath, res)
}
_, err = out.Write(res)
return err
}
func writeIndividualFiles(
fSys filesys.FileSystem, folderPath string, m resmap.ResMap) error {
byNamespace := m.GroupedByCurrentNamespace()
for namespace, resList := range byNamespace {
for _, res := range resList {
fName := fileName(res)
if len(byNamespace) > 1 {
fName = strings.ToLower(namespace) + "_" + fName
}
err := writeFile(fSys, folderPath, fName, res)
if err != nil {
return err
}
}
}
for _, res := range m.NonNamespaceable() {
err := writeFile(fSys, folderPath, fileName(res), res)
if err != nil {
return err
}
}
return nil
}
func fileName(res *resource.Resource) string {
return strings.ToLower(res.GetGvk().StringWoEmptyField()) +
"_" + strings.ToLower(res.GetName()) + ".yaml"
}
func writeFile(
fSys filesys.FileSystem, path, fName string, res *resource.Resource) error {
out, err := yaml.Marshal(res.Map())
if err != nil {
return err
}
return fSys.WriteFile(filepath.Join(path, fName), out)
kOpts.AddManagedbyLabel = isManagedbyLabelEnabled()
kOpts.UseKyaml = konfig.FlagEnableKyamlDefaultValue
kOpts.AllowResourceIdChanges = flagAllowResourceIdChangesValue
return kOpts
}

View File

@@ -19,7 +19,7 @@ var (
flagEnableManagedbyLabelValue = false
)
func addFlagEnableManagedbyLabel(set *pflag.FlagSet) {
func AddFlagEnableManagedbyLabel(set *pflag.FlagSet) {
set.BoolVar(
&flagEnableManagedbyLabelValue, flagEnableManagedbyLabelName,
false, flagEnableManagedbyLabelHelp)

View File

@@ -16,7 +16,7 @@ var (
flagAllowResourceIdChangesValue = false
)
func addFlagAllowResourceIdChanges(set *pflag.FlagSet) {
func AddFlagAllowResourceIdChanges(set *pflag.FlagSet) {
set.BoolVar(
&flagAllowResourceIdChangesValue, flagAllowResourceIdChangesName,
false, flagAllowResourceIdChangesHelp)

View File

@@ -18,7 +18,7 @@ var (
flagPluginsEnabledValue = false
)
func addFlagEnablePlugins(set *pflag.FlagSet) {
func AddFlagEnablePlugins(set *pflag.FlagSet) {
set.BoolVar(
&flagPluginsEnabledValue, flagEnablePluginsName,
false, flagEnablePluginsHelp)

View File

@@ -21,7 +21,7 @@ var (
"This does, however, break the relocatability of the kustomization."
)
func addFlagLoadRestrictor(set *pflag.FlagSet) {
func AddFlagLoadRestrictor(set *pflag.FlagSet) {
set.StringVar(
&flagLrValue, flagName,
types.LoadRestrictionsRootOnly.String(), flagLrHelp)

View File

@@ -0,0 +1,30 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package build
import (
"github.com/spf13/pflag"
"sigs.k8s.io/kustomize/api/types"
)
func AddFunctionFlags(set *pflag.FlagSet, o *types.FnPluginLoadingOptions) {
set.BoolVar(
&o.EnableExec, "enable-exec", false, /*do not change!*/
"enable support for exec functions -- note: exec functions run arbitrary code -- do not use for untrusted configs!!! (Alpha)")
set.BoolVar(
&o.EnableStar, "enable-star", false,
"enable support for starlark functions. (Alpha)")
set.BoolVar(
&o.Network, "network", false,
"enable network access for functions that declare it")
set.StringVar(
&o.NetworkName, "network-name", "bridge",
"the docker network to run the container in")
set.StringArrayVar(
&o.Mounts, "mount", []string{},
"a list of storage options read from the filesystem")
set.StringArrayVarP(
&o.Env, "env", "e", []string{},
"a list of environment variables to be used by functions")
}

View File

@@ -29,7 +29,7 @@ var (
"Use '" + none.String() + "' to suppress a final reordering."
)
func addFlagReorderOutput(set *pflag.FlagSet) {
func AddFlagReorderOutput(set *pflag.FlagSet) {
set.StringVar(
&flagReorderOutputValue, flagReorderOutputName,
legacy.String(), flagReorderOutputHelp)

View File

@@ -0,0 +1,59 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package build
import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/yaml"
)
type Writer struct {
fSys filesys.FileSystem
}
func MakeWriter(fSys filesys.FileSystem) *Writer {
return &Writer{
fSys: fSys,
}
}
func (w Writer) WriteIndividualFiles(dirPath string, m resmap.ResMap) error {
byNamespace := m.GroupedByCurrentNamespace()
for namespace, resList := range byNamespace {
for _, res := range resList {
fName := fileName(res)
if len(byNamespace) > 1 {
fName = strings.ToLower(namespace) + "_" + fName
}
if err := w.write(dirPath, fName, res); err != nil {
return err
}
}
}
for _, res := range m.NonNamespaceable() {
err := w.write(dirPath, fileName(res), res)
if err != nil {
return err
}
}
return nil
}
func (w Writer) write(path, fName string, res *resource.Resource) error {
yml, err := yaml.Marshal(res.Map())
if err != nil {
return err
}
return w.fSys.WriteFile(filepath.Join(path, fName), yml)
}
func fileName(res *resource.Resource) string {
return strings.ToLower(res.GetGvk().StringWoEmptyField()) +
"_" + strings.ToLower(res.GetName()) + ".yaml"
}