Skip to content

Commit

Permalink
feat: allow and deny list support for schema field overwriting (namel…
Browse files Browse the repository at this point in the history
…y label and image fields atm)
  • Loading branch information
aaron-prindle committed Jan 26, 2022
1 parent 81dd394 commit 9bb7832
Show file tree
Hide file tree
Showing 18 changed files with 437 additions and 1,266 deletions.
16 changes: 16 additions & 0 deletions cmd/skaffold/app/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,22 @@ var flagRegistry = []Flag{
FlagAddMethod: "BoolVar",
DefinedOn: []string{"deploy"},
},
{
Name: "transformableAllowListFile",
Usage: "Path to JSON file specififying the allow list of yaml objects for skaffold to NOT transform with 'image' and 'label' field replacements. NOTE: this list is additive to skaffold's default allowlist",
Value: &opts.TransformableAllowListFile,
DefValue: "",
FlagAddMethod: "String",
DefinedOn: []string{"dev", "run", "debug", "deploy"},
},
{
Name: "transformableDenyListFile",
Usage: "Path to JSON file specififying the deny list of yaml objects for skaffold to NOT transform with 'image' and 'label' field replacements. NOTE: this list is additive to skaffold's default denylist",
Value: &opts.TransformableDenyListFile,
DefValue: "",
FlagAddMethod: "StringVar",
DefinedOn: []string{"dev", "run", "debug", "deploy"},
},
}

func methodNameByType(v reflect.Value) string {
Expand Down
1,132 changes: 0 additions & 1,132 deletions docs/content/en/docs/references/cli/_index.md

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions pkg/skaffold/config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ type SkaffoldOptions struct {
// TODO(https://github.com/GoogleContainerTools/skaffold/issues/3668):
// remove minikubeProfile from here and instead detect it by matching the
// kubecontext API Server to minikube profiles
MinikubeProfile string
Namespace string
RenderOutput string
RepoCacheDir string
Trigger string
User string
MinikubeProfile string
Namespace string
RenderOutput string
RepoCacheDir string
Trigger string
User string
TransformableAllowListFile string
TransformableDenyListFile string

ConfigurationFilter []string
CustomLabels []string
Expand Down
3 changes: 3 additions & 0 deletions pkg/skaffold/deploy/deploy_problems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,6 @@ func (m mockConfig) GetKubeContext() string { return
func (m mockConfig) GetInsecureRegistries() map[string]bool { return map[string]bool{} }
func (m mockConfig) Mode() config.RunMode { return config.RunModes.Dev }
func (m mockConfig) TransformableAllowList() []latestV1.ResourceFilter { return nil }
func (m mockConfig) TransformableDenyList() []latestV1.ResourceFilter { return nil }
func (m mockConfig) GetTransformableAllowListFile() string { return "" }
func (m mockConfig) GetTransformableDenyListFile() string { return "" }
57 changes: 38 additions & 19 deletions pkg/skaffold/deploy/kpt/kpt.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8syaml "sigs.k8s.io/yaml"

apimachinery "k8s.io/apimachinery/pkg/runtime/schema"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/access"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/debug"
Expand Down Expand Up @@ -100,6 +102,9 @@ type Deployer struct {
namespace string

namespaces *[]string

transformableAllowlist map[apimachinery.GroupKind]latestV1.ResourceFilter
transformableDenylist map[apimachinery.GroupKind]latestV1.ResourceFilter
}

type Config interface {
Expand All @@ -118,23 +123,37 @@ func NewDeployer(cfg Config, labeller *label.DefaultLabeller, d *latestV1.KptDep
olog.Entry(context.TODO()).Warn("unable to parse namespaces - deploy might not work correctly!")
}
logger := component.NewLogger(cfg, kubectl, podSelector, &namespaces)

transformableAllowlist := map[apimachinery.GroupKind]latestV1.ResourceFilter{}
for _, rf := range cfg.TransformableAllowList() {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableAllowlist[groupKind] = rf
}

transformableDenylist := map[apimachinery.GroupKind]latestV1.ResourceFilter{}
for _, rf := range cfg.TransformableDenyList() {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableDenylist[groupKind] = rf
}
return &Deployer{
KptDeploy: d,
podSelector: podSelector,
namespaces: &namespaces,
accessor: component.NewAccessor(cfg, cfg.GetKubeContext(), kubectl, podSelector, labeller, &namespaces),
debugger: component.NewDebugger(cfg.Mode(), podSelector, &namespaces, cfg.GetKubeContext()),
imageLoader: component.NewImageLoader(cfg, kubectl),
logger: logger,
statusMonitor: component.NewMonitor(cfg, cfg.GetKubeContext(), labeller, &namespaces),
syncer: component.NewSyncer(kubectl, &namespaces, logger.GetFormatter()),
insecureRegistries: cfg.GetInsecureRegistries(),
labels: labeller.Labels(),
globalConfig: cfg.GlobalConfig(),
hasKustomization: hasKustomization,
kubeContext: cfg.GetKubeContext(),
kubeConfig: cfg.GetKubeConfig(),
namespace: cfg.GetKubeNamespace(),
KptDeploy: d,
podSelector: podSelector,
namespaces: &namespaces,
accessor: component.NewAccessor(cfg, cfg.GetKubeContext(), kubectl, podSelector, labeller, &namespaces),
debugger: component.NewDebugger(cfg.Mode(), podSelector, &namespaces, cfg.GetKubeContext()),
imageLoader: component.NewImageLoader(cfg, kubectl),
logger: logger,
statusMonitor: component.NewMonitor(cfg, cfg.GetKubeContext(), labeller, &namespaces),
syncer: component.NewSyncer(kubectl, &namespaces, logger.GetFormatter()),
insecureRegistries: cfg.GetInsecureRegistries(),
labels: labeller.Labels(),
globalConfig: cfg.GlobalConfig(),
hasKustomization: hasKustomization,
kubeContext: cfg.GetKubeContext(),
kubeConfig: cfg.GetKubeConfig(),
namespace: cfg.GetKubeNamespace(),
transformableAllowlist: transformableAllowlist,
transformableDenylist: transformableDenylist,
}
}

Expand Down Expand Up @@ -475,12 +494,12 @@ func (k *Deployer) renderManifests(ctx context.Context, builds []graph.Artifact)
return nil, fmt.Errorf("excluding kpt functions from manifests: %w", err)
}
if k.originalImages == nil {
k.originalImages, err = manifests.GetImages()
k.originalImages, err = manifests.GetImages(k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return nil, err
}
}
manifests, err = manifests.ReplaceImages(ctx, builds)
manifests, err = manifests.ReplaceImages(ctx, builds, k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return nil, fmt.Errorf("replacing images in manifests: %w", err)
}
Expand All @@ -489,7 +508,7 @@ func (k *Deployer) renderManifests(ctx context.Context, builds []graph.Artifact)
return nil, err
}

return manifests.SetLabels(k.labels)
return manifests.SetLabels(k.labels, k.transformableAllowlist, k.transformableDenylist)
}

func sink(ctx context.Context, buf []byte, sinkDir string) error {
Expand Down
106 changes: 80 additions & 26 deletions pkg/skaffold/deploy/kubectl/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package kubectl
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand All @@ -27,6 +28,7 @@ import (

"github.com/segmentio/textio"
"go.opentelemetry.io/otel/trace"
apimachinery "k8s.io/apimachinery/pkg/runtime/schema"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/access"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
Expand Down Expand Up @@ -80,6 +82,9 @@ type Deployer struct {
skipRender bool

namespaces *[]string

transformableAllowlist map[apimachinery.GroupKind]latestV1.ResourceFilter
transformableDenylist map[apimachinery.GroupKind]latestV1.ResourceFilter
}

// NewDeployer returns a new Deployer for a DeployConfig filled
Expand All @@ -102,26 +107,75 @@ func NewDeployer(cfg Config, labeller *label.DefaultLabeller, d *latestV1.Kubect
}
logger := component.NewLogger(cfg, kubectl.CLI, podSelector, &namespaces)

transformableAllowlist := map[apimachinery.GroupKind]latestV1.ResourceFilter{}
for _, rf := range cfg.TransformableAllowList() {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableAllowlist[groupKind] = rf
}

transformableDenylist := map[apimachinery.GroupKind]latestV1.ResourceFilter{}
for _, rf := range cfg.TransformableDenyList() {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableDenylist[groupKind] = rf
}

// TODO(aaron-prindle) verfiy if workdir needs to be considered more in this read...
if cfg.GetTransformableAllowListFile() != "" {
transformableAllowlistFromFile, err := ioutil.ReadFile(cfg.GetTransformableAllowListFile())
if err != nil {
panic(err)
}
rfs := []latestV1.ResourceFilter{}
err = json.Unmarshal(transformableAllowlistFromFile, &rfs)
if err != nil {
panic(err)
}
for _, rf := range rfs {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableDenylist[groupKind] = rf
}
}

if cfg.GetTransformableDenyListFile() != "" {
// TODO(aaron-prindle) verfiy if workdir needs to be considered more in this read...
transformableDenylistFromFile, err := ioutil.ReadFile(cfg.GetTransformableDenyListFile())
if err != nil {
panic(err)
}
// TODO(aaron-prindle) verify if it is needed to re-zero rfs
rfs := []latestV1.ResourceFilter{}
err = json.Unmarshal(transformableDenylistFromFile, &rfs)
if err != nil {
panic(err)
}
for _, rf := range rfs {
groupKind := apimachinery.ParseGroupKind(rf.Type)
transformableDenylist[groupKind] = rf
}
}

return &Deployer{
KubectlDeploy: d,
podSelector: podSelector,
namespaces: &namespaces,
accessor: component.NewAccessor(cfg, cfg.GetKubeContext(), kubectl.CLI, podSelector, labeller, &namespaces),
debugger: component.NewDebugger(cfg.Mode(), podSelector, &namespaces, cfg.GetKubeContext()),
imageLoader: component.NewImageLoader(cfg, kubectl.CLI),
logger: logger,
statusMonitor: component.NewMonitor(cfg, cfg.GetKubeContext(), labeller, &namespaces),
syncer: component.NewSyncer(kubectl.CLI, &namespaces, logger.GetFormatter()),
hookRunner: hooks.NewDeployRunner(kubectl.CLI, d.LifecycleHooks, &namespaces, logger.GetFormatter(), hooks.NewDeployEnvOpts(labeller.GetRunID(), kubectl.KubeContext, namespaces)),
workingDir: cfg.GetWorkingDir(),
globalConfig: cfg.GlobalConfig(),
defaultRepo: cfg.DefaultRepo(),
multiLevelRepo: cfg.MultiLevelRepo(),
kubectl: kubectl,
insecureRegistries: cfg.GetInsecureRegistries(),
skipRender: cfg.SkipRender(),
labeller: labeller,
hydratedManifests: cfg.HydratedManifests(),
KubectlDeploy: d,
podSelector: podSelector,
namespaces: &namespaces,
accessor: component.NewAccessor(cfg, cfg.GetKubeContext(), kubectl.CLI, podSelector, labeller, &namespaces),
debugger: component.NewDebugger(cfg.Mode(), podSelector, &namespaces, cfg.GetKubeContext()),
imageLoader: component.NewImageLoader(cfg, kubectl.CLI),
logger: logger,
statusMonitor: component.NewMonitor(cfg, cfg.GetKubeContext(), labeller, &namespaces),
syncer: component.NewSyncer(kubectl.CLI, &namespaces, logger.GetFormatter()),
hookRunner: hooks.NewDeployRunner(kubectl.CLI, d.LifecycleHooks, &namespaces, logger.GetFormatter(), hooks.NewDeployEnvOpts(labeller.GetRunID(), kubectl.KubeContext, namespaces)),
workingDir: cfg.GetWorkingDir(),
globalConfig: cfg.GlobalConfig(),
defaultRepo: cfg.DefaultRepo(),
multiLevelRepo: cfg.MultiLevelRepo(),
kubectl: kubectl,
insecureRegistries: cfg.GetInsecureRegistries(),
skipRender: cfg.SkipRender(),
labeller: labeller,
hydratedManifests: cfg.HydratedManifests(),
transformableAllowlist: transformableAllowlist,
transformableDenylist: transformableDenylist,
}, nil
}

Expand Down Expand Up @@ -188,7 +242,7 @@ func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Art
endTrace(instrumentation.TraceEndError(err))
return err
}
manifests, err = manifests.SetLabels(k.labeller.Labels())
manifests, err = manifests.SetLabels(k.labeller.Labels(), k.transformableAllowlist, k.transformableDenylist)
endTrace()
case k.skipRender:
childCtx, endTrace = instrumentation.StartTrace(ctx, "Deploy_readManifests")
Expand All @@ -197,7 +251,7 @@ func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Art
endTrace(instrumentation.TraceEndError(err))
return err
}
manifests, err = manifests.SetLabels(k.labeller.Labels())
manifests, err = manifests.SetLabels(k.labeller.Labels(), k.transformableAllowlist, k.transformableDenylist)
endTrace()
default:
childCtx, endTrace = instrumentation.StartTrace(ctx, "Deploy_renderManifests")
Expand Down Expand Up @@ -434,7 +488,7 @@ func (k *Deployer) renderManifests(ctx context.Context, out io.Writer, builds []
originalManifests := append(localManifests, remoteManifests...)

if len(k.originalImages) == 0 {
k.originalImages, err = originalManifests.GetImages()
k.originalImages, err = originalManifests.GetImages(k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return nil, err
}
Expand All @@ -457,13 +511,13 @@ func (k *Deployer) renderManifests(ctx context.Context, out io.Writer, builds []
}
}
if len(remoteManifests) > 0 {
remoteManifests, err = remoteManifests.ReplaceRemoteManifestImages(ctx, builds)
remoteManifests, err = remoteManifests.ReplaceRemoteManifestImages(ctx, builds, k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return nil, err
}
}
if len(localManifests) > 0 {
localManifests, err = localManifests.ReplaceImages(ctx, builds)
localManifests, err = localManifests.ReplaceImages(ctx, builds, k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return nil, err
}
Expand All @@ -475,7 +529,7 @@ func (k *Deployer) renderManifests(ctx context.Context, out io.Writer, builds []
return nil, err
}

return modifiedManifests.SetLabels(k.labeller.Labels())
return modifiedManifests.SetLabels(k.labeller.Labels(), k.transformableAllowlist, k.transformableDenylist)
}

// Cleanup deletes what was deployed by calling Deploy.
Expand Down Expand Up @@ -506,7 +560,7 @@ func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool) erro
rm = append(rm, manifest)
}

upd, err := rm.ReplaceRemoteManifestImages(ctx, k.originalImages)
upd, err := rm.ReplaceRemoteManifestImages(ctx, k.originalImages, k.transformableAllowlist, k.transformableDenylist)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 9bb7832

Please sign in to comment.