mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 09:24:23 +00:00
Add load_restrictor flag.
This commit is contained in:
2
go.mod
2
go.mod
@@ -25,7 +25,7 @@ require (
|
|||||||
github.com/onsi/gomega v1.5.0 // indirect
|
github.com/onsi/gomega v1.5.0 // indirect
|
||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/spf13/cobra v0.0.2
|
github.com/spf13/cobra v0.0.2
|
||||||
github.com/spf13/pflag v1.0.1 // indirect
|
github.com/spf13/pflag v1.0.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20190225153610-fe579d43d832 // indirect
|
golang.org/x/net v0.0.0-20190225153610-fe579d43d832 // indirect
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import (
|
|||||||
type Options struct {
|
type Options struct {
|
||||||
kustomizationPath string
|
kustomizationPath string
|
||||||
outputPath string
|
outputPath string
|
||||||
|
loadRestrictor loader.LoadRestrictorFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOptions creates a Options object
|
// NewOptions creates a Options object
|
||||||
@@ -45,6 +46,7 @@ func NewOptions(p, o string) *Options {
|
|||||||
return &Options{
|
return &Options{
|
||||||
kustomizationPath: p,
|
kustomizationPath: p,
|
||||||
outputPath: o,
|
outputPath: o,
|
||||||
|
loadRestrictor: loader.RestrictionRootOnly,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,13 +90,14 @@ func NewCmdBuild(
|
|||||||
&o.outputPath,
|
&o.outputPath,
|
||||||
"output", "o", "",
|
"output", "o", "",
|
||||||
"If specified, write the build output to this path.")
|
"If specified, write the build output to this path.")
|
||||||
|
loader.AddLoadRestrictionsFlag(cmd.Flags())
|
||||||
|
|
||||||
cmd.AddCommand(NewCmdBuildPrune(out, fs, rf, ptf, pc))
|
cmd.AddCommand(NewCmdBuildPrune(out, fs, rf, ptf, pc))
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates build command.
|
// Validate validates build command.
|
||||||
func (o *Options) Validate(args []string) error {
|
func (o *Options) Validate(args []string) (err error) {
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
return errors.New(
|
return errors.New(
|
||||||
"specify one path to " + pgmconfig.KustomizationFileNames[0])
|
"specify one path to " + pgmconfig.KustomizationFileNames[0])
|
||||||
@@ -104,8 +107,8 @@ func (o *Options) Validate(args []string) error {
|
|||||||
} else {
|
} else {
|
||||||
o.kustomizationPath = args[0]
|
o.kustomizationPath = args[0]
|
||||||
}
|
}
|
||||||
|
o.loadRestrictor, err = loader.ValidateLoadRestrictorFlag()
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunBuild runs build command.
|
// RunBuild runs build command.
|
||||||
@@ -113,7 +116,8 @@ func (o *Options) RunBuild(
|
|||||||
out io.Writer, fSys fs.FileSystem,
|
out io.Writer, fSys fs.FileSystem,
|
||||||
rf *resmap.Factory, ptf transformer.Factory,
|
rf *resmap.Factory, ptf transformer.Factory,
|
||||||
pc *types.PluginConfig) error {
|
pc *types.PluginConfig) error {
|
||||||
ldr, err := loader.NewLoader(o.kustomizationPath, fSys)
|
ldr, err := loader.NewLoader(
|
||||||
|
o.loadRestrictor, o.kustomizationPath, fSys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -133,7 +137,8 @@ func (o *Options) RunBuildPrune(
|
|||||||
out io.Writer, fSys fs.FileSystem,
|
out io.Writer, fSys fs.FileSystem,
|
||||||
rf *resmap.Factory, ptf transformer.Factory,
|
rf *resmap.Factory, ptf transformer.Factory,
|
||||||
pc *types.PluginConfig) error {
|
pc *types.PluginConfig) error {
|
||||||
ldr, err := loader.NewLoader(o.kustomizationPath, fSys)
|
ldr, err := loader.NewLoader(
|
||||||
|
o.loadRestrictor, o.kustomizationPath, fSys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,22 @@ type FakeLoader struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewFakeLoader returns a Loader that uses a fake filesystem.
|
// NewFakeLoader returns a Loader that uses a fake filesystem.
|
||||||
// The argument should be an absolute file path.
|
// The loader will be restricted to root only.
|
||||||
|
// The initialDir argument should be an absolute file path.
|
||||||
func NewFakeLoader(initialDir string) FakeLoader {
|
func NewFakeLoader(initialDir string) FakeLoader {
|
||||||
|
return NewFakeLoaderWithRestrictor(
|
||||||
|
loader.RestrictionRootOnly, initialDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFakeLoaderWithRestrictor returns a Loader that
|
||||||
|
// uses a fake filesystem.
|
||||||
|
// The initialDir argument should be an absolute file path.
|
||||||
|
func NewFakeLoaderWithRestrictor(
|
||||||
|
lr loader.LoadRestrictorFunc, initialDir string) FakeLoader {
|
||||||
// Create fake filesystem and inject it into initial Loader.
|
// Create fake filesystem and inject it into initial Loader.
|
||||||
fSys := fs.MakeFakeFS()
|
fSys := fs.MakeFakeFS()
|
||||||
fSys.Mkdir(initialDir)
|
fSys.Mkdir(initialDir)
|
||||||
ldr, err := loader.NewLoader(initialDir, fSys)
|
ldr, err := loader.NewLoader(lr, initialDir, fSys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to make loader: %v", err)
|
log.Fatalf("Unable to make loader: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ func doSanityChecksAndDropIntoBase(
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRestrictionRootInRealLoader(t *testing.T) {
|
func TestRestrictionRootOnlyInRealLoader(t *testing.T) {
|
||||||
dir, fSys, err := commonSetupForLoaderRestrictionTest()
|
dir, fSys, err := commonSetupForLoaderRestrictionTest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
|||||||
@@ -26,10 +26,11 @@ import (
|
|||||||
// NewLoader returns a Loader pointed at the given target.
|
// NewLoader returns a Loader pointed at the given target.
|
||||||
// If the target is remote, the loader will be restricted
|
// If the target is remote, the loader will be restricted
|
||||||
// to the root and below only. If the target is local, the
|
// to the root and below only. If the target is local, the
|
||||||
// loader will have no restrictions. If the local target
|
// loader will have the restrictions passed in. Regardless,
|
||||||
// attempts to transitively load remote bases, they will all
|
// if a local target attempts to transitively load remote bases,
|
||||||
// be root-only restricted.
|
// the remote bases will all be root-only restricted.
|
||||||
func NewLoader(
|
func NewLoader(
|
||||||
|
lr LoadRestrictorFunc,
|
||||||
target string, fSys fs.FileSystem) (ifc.Loader, error) {
|
target string, fSys fs.FileSystem) (ifc.Loader, error) {
|
||||||
repoSpec, err := git.NewRepoSpecFromUrl(target)
|
repoSpec, err := git.NewRepoSpecFromUrl(target)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -42,5 +43,5 @@ func NewLoader(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return newLoaderAtConfirmedDir(
|
return newLoaderAtConfirmedDir(
|
||||||
RestrictionNone, root, fSys, nil, git.ClonerUsingGitExec), nil
|
lr, root, fSys, nil, git.ClonerUsingGitExec), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,50 @@ package loader
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/pflag"
|
||||||
"sigs.k8s.io/kustomize/pkg/fs"
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=loadRestrictions
|
||||||
|
type loadRestrictions int
|
||||||
|
|
||||||
|
const (
|
||||||
|
unknown loadRestrictions = iota
|
||||||
|
rootOnly
|
||||||
|
none
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagName = "load_restrictor"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagValue = rootOnly.String()
|
||||||
|
flagHelp = "if set to '" + none.String() +
|
||||||
|
"', local kustomizations may load files from outside their root. " +
|
||||||
|
"This does, however, break the relocatability of the kustomization."
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddLoadRestrictionsFlag(set *pflag.FlagSet) {
|
||||||
|
set.StringVar(
|
||||||
|
&flagValue, flagName,
|
||||||
|
rootOnly.String(), flagHelp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateLoadRestrictorFlag() (LoadRestrictorFunc, error) {
|
||||||
|
switch flagValue {
|
||||||
|
case rootOnly.String():
|
||||||
|
return RestrictionRootOnly, nil
|
||||||
|
case none.String():
|
||||||
|
return RestrictionNone, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"illegal flag value --%s %s; legal values: %v",
|
||||||
|
flagName, flagValue,
|
||||||
|
[]string{rootOnly.String(), none.String()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type LoadRestrictorFunc func(
|
type LoadRestrictorFunc func(
|
||||||
fs.FileSystem, fs.ConfirmedDir, string) (string, error)
|
fs.FileSystem, fs.ConfirmedDir, string) (string, error)
|
||||||
|
|
||||||
|
|||||||
25
pkg/loader/loadrestrictions_string.go
Normal file
25
pkg/loader/loadrestrictions_string.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Code generated by "stringer -type=loadRestrictions"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package loader
|
||||||
|
|
||||||
|
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[unknown-0]
|
||||||
|
_ = x[rootOnly-1]
|
||||||
|
_ = x[none-2]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _loadRestrictions_name = "unknownrootOnlynone"
|
||||||
|
|
||||||
|
var _loadRestrictions_index = [...]uint8{0, 7, 15, 19}
|
||||||
|
|
||||||
|
func (i loadRestrictions) String() string {
|
||||||
|
if i < 0 || i >= loadRestrictions(len(_loadRestrictions_index)-1) {
|
||||||
|
return "loadRestrictions(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _loadRestrictions_name[_loadRestrictions_index[i]:_loadRestrictions_index[i+1]]
|
||||||
|
}
|
||||||
@@ -17,7 +17,11 @@ limitations under the License.
|
|||||||
package target_test
|
package target_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/loader"
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeSmallBase(th *KustTestHarness) {
|
func writeSmallBase(th *KustTestHarness) {
|
||||||
@@ -181,8 +185,42 @@ spec:
|
|||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSharedPatchDisAllowed(t *testing.T) {
|
||||||
|
th := NewKustTestHarnessFull(
|
||||||
|
t, "/app/overlay",
|
||||||
|
loader.RestrictionRootOnly, plugin.DefaultPluginConfig())
|
||||||
|
writeSmallBase(th)
|
||||||
|
th.writeK("/app/overlay", `
|
||||||
|
commonLabels:
|
||||||
|
env: prod
|
||||||
|
bases:
|
||||||
|
- ../base
|
||||||
|
patchesStrategicMerge:
|
||||||
|
- ../shared/deployment-patch.yaml
|
||||||
|
`)
|
||||||
|
th.writeF("/app/shared/deployment-patch.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
replicas: 1000
|
||||||
|
`)
|
||||||
|
_, err := th.makeKustTarget().MakeCustomizedResMap()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(
|
||||||
|
err.Error(),
|
||||||
|
"security; file '/app/shared/deployment-patch.yaml' is not in or below '/app/overlay'") {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSharedPatchAllowed(t *testing.T) {
|
func TestSharedPatchAllowed(t *testing.T) {
|
||||||
th := NewKustTestHarness(t, "/app/overlay")
|
th := NewKustTestHarnessFull(
|
||||||
|
t, "/app/overlay",
|
||||||
|
loader.RestrictionNone, plugin.DefaultPluginConfig())
|
||||||
writeSmallBase(th)
|
writeSmallBase(th)
|
||||||
th.writeK("/app/overlay", `
|
th.writeK("/app/overlay", `
|
||||||
commonLabels:
|
commonLabels:
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
||||||
"sigs.k8s.io/kustomize/k8sdeps/transformer"
|
"sigs.k8s.io/kustomize/k8sdeps/transformer"
|
||||||
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
|
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/loader"
|
||||||
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
"sigs.k8s.io/kustomize/pkg/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
"sigs.k8s.io/kustomize/pkg/resource"
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
@@ -51,12 +52,18 @@ func NewKustTestHarness(t *testing.T, path string) *KustTestHarness {
|
|||||||
func NewKustTestHarnessWithPluginConfig(
|
func NewKustTestHarnessWithPluginConfig(
|
||||||
t *testing.T, path string,
|
t *testing.T, path string,
|
||||||
pc *types.PluginConfig) *KustTestHarness {
|
pc *types.PluginConfig) *KustTestHarness {
|
||||||
|
return NewKustTestHarnessFull(t, path, loader.RestrictionRootOnly, pc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKustTestHarnessFull(
|
||||||
|
t *testing.T, path string,
|
||||||
|
lr loader.LoadRestrictorFunc, pc *types.PluginConfig) *KustTestHarness {
|
||||||
return &KustTestHarness{
|
return &KustTestHarness{
|
||||||
t: t,
|
t: t,
|
||||||
rf: resmap.NewFactory(resource.NewFactory(
|
rf: resmap.NewFactory(resource.NewFactory(
|
||||||
kunstruct.NewKunstructuredFactoryWithGeneratorArgs(
|
kunstruct.NewKunstructuredFactoryWithGeneratorArgs(
|
||||||
&types.GeneratorMetaArgs{PluginConfig: pc}))),
|
&types.GeneratorMetaArgs{PluginConfig: pc}))),
|
||||||
ldr: loadertest.NewFakeLoader(path),
|
ldr: loadertest.NewFakeLoaderWithRestrictor(lr, path),
|
||||||
pc: pc}
|
pc: pc}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user