Skip to content

Commit

Permalink
Support configuring default namespace for kubectl/kustomize deployers
Browse files Browse the repository at this point in the history
  • Loading branch information
AndiDog committed Jun 23, 2020
1 parent 9d2bab8 commit 66c1fa8
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 18 deletions.
16 changes: 14 additions & 2 deletions docs/content/en/schemas/v2beta5.json
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,11 @@
},
"KubectlDeploy": {
"properties": {
"defaultNamespace": {
"type": "string",
"description": "default namespace passed to kubectl on deployment if no other override is given.",
"x-intellij-html-description": "default namespace passed to kubectl on deployment if no other override is given."
},
"flags": {
"$ref": "#/definitions/KubectlFlags",
"description": "additional flags passed to `kubectl`.",
Expand Down Expand Up @@ -1595,7 +1600,8 @@
"preferredOrder": [
"manifests",
"remoteManifests",
"flags"
"flags",
"defaultNamespace"
],
"additionalProperties": false,
"description": "*beta* uses a client side `kubectl apply` to deploy manifests. You'll need a `kubectl` CLI version installed that's compatible with your cluster.",
Expand Down Expand Up @@ -1658,6 +1664,11 @@
"x-intellij-html-description": "additional args passed to <code>kustomize build</code>.",
"default": "[]"
},
"defaultNamespace": {
"type": "string",
"description": "default namespace passed to kubectl on deployment if no other override is given.",
"x-intellij-html-description": "default namespace passed to kubectl on deployment if no other override is given."
},
"flags": {
"$ref": "#/definitions/KubectlFlags",
"description": "additional flags passed to `kubectl`.",
Expand All @@ -1676,7 +1687,8 @@
"preferredOrder": [
"paths",
"flags",
"buildArgs"
"buildArgs",
"defaultNamespace"
],
"additionalProperties": false,
"description": "*beta* uses the `kustomize` CLI to \"patch\" a deployment for a target environment.",
Expand Down
1 change: 1 addition & 0 deletions pkg/skaffold/deploy/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ var testTwoReleases = latest.HelmDeploy{
}

var testNamespace = "testNamespace"
var testNamespace2 = "testNamespace2"

var validDeployYaml = `
# Source: skaffold-helm/templates/deployment.yaml
Expand Down
7 changes: 6 additions & 1 deletion pkg/skaffold/deploy/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,18 @@ type KubectlDeployer struct {
// NewKubectlDeployer returns a new KubectlDeployer for a DeployConfig filled
// with the needed configuration for `kubectl apply`
func NewKubectlDeployer(runCtx *runcontext.RunContext) *KubectlDeployer {
defaultNamespace := ""
if runCtx.Cfg.Deploy.KubectlDeploy.DefaultNamespace != nil {
defaultNamespace = *runCtx.Cfg.Deploy.KubectlDeploy.DefaultNamespace
}

return &KubectlDeployer{
KubectlDeploy: runCtx.Cfg.Deploy.KubectlDeploy,
workingDir: runCtx.WorkingDir,
globalConfig: runCtx.Opts.GlobalConfig,
defaultRepo: runCtx.Opts.DefaultRepo.Value(),
kubectl: deploy.CLI{
CLI: kubectl.NewFromRunContext(runCtx),
CLI: kubectl.NewFromRunContextAndDefaultNamespace(runCtx, defaultNamespace),
Flags: runCtx.Cfg.Deploy.KubectlDeploy.Flags,
ForceDeploy: runCtx.Opts.Force,
},
Expand Down
36 changes: 29 additions & 7 deletions pkg/skaffold/deploy/kubectl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ spec:

func TestKubectlDeploy(t *testing.T) {
tests := []struct {
description string
cfg *latest.KubectlDeploy
builds []build.Artifact
commands util.Command
shouldErr bool
forceDeploy bool
description string
cfg *latest.KubectlDeploy
builds []build.Artifact
commands util.Command
shouldErr bool
forceDeploy bool
skipSkaffoldNamespaceOption bool
}{
{
description: "no manifest",
Expand Down Expand Up @@ -133,6 +134,22 @@ func TestKubectlDeploy(t *testing.T) {
Tag: "leeroy-web:123",
}},
},
{
description: "deploy success (default namespace)",
cfg: &latest.KubectlDeploy{
Manifests: []string{"deployment.yaml"},
DefaultNamespace: &testNamespace2,
},
commands: testutil.
CmdRunOut("kubectl version --client -ojson", kubectlVersion118).
AndRunOut("kubectl --context kubecontext --namespace testNamespace2 create --dry-run=client -oyaml -f deployment.yaml", deploymentWebYAML).
AndRun("kubectl --context kubecontext --namespace testNamespace2 apply -f -"),
builds: []build.Artifact{{
ImageName: "leeroy-web",
Tag: "leeroy-web:123",
}},
skipSkaffoldNamespaceOption: true,
},
{
description: "http manifest",
cfg: &latest.KubectlDeploy{
Expand Down Expand Up @@ -191,6 +208,11 @@ func TestKubectlDeploy(t *testing.T) {
Touch("empty.ignored").
Chdir()

skaffoldNamespaceOption := ""
if !test.skipSkaffoldNamespaceOption {
skaffoldNamespaceOption = testNamespace
}

k := NewKubectlDeployer(&runcontext.RunContext{
WorkingDir: ".",
Cfg: latest.Pipeline{
Expand All @@ -202,7 +224,7 @@ func TestKubectlDeploy(t *testing.T) {
},
KubeContext: testKubeContext,
Opts: config.SkaffoldOptions{
Namespace: testNamespace,
Namespace: skaffoldNamespaceOption,
Force: test.forceDeploy,
},
})
Expand Down
7 changes: 6 additions & 1 deletion pkg/skaffold/deploy/kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,15 @@ type KustomizeDeployer struct {
}

func NewKustomizeDeployer(runCtx *runcontext.RunContext) *KustomizeDeployer {
defaultNamespace := ""
if runCtx.Cfg.Deploy.KustomizeDeploy.DefaultNamespace != nil {
defaultNamespace = *runCtx.Cfg.Deploy.KustomizeDeploy.DefaultNamespace
}

return &KustomizeDeployer{
KustomizeDeploy: runCtx.Cfg.Deploy.KustomizeDeploy,
kubectl: deploy.CLI{
CLI: kubectl.NewFromRunContext(runCtx),
CLI: kubectl.NewFromRunContextAndDefaultNamespace(runCtx, defaultNamespace),
Flags: runCtx.Cfg.Deploy.KustomizeDeploy.Flags,
ForceDeploy: runCtx.Opts.Force,
},
Expand Down
37 changes: 30 additions & 7 deletions pkg/skaffold/deploy/kustomize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ import (

func TestKustomizeDeploy(t *testing.T) {
tests := []struct {
description string
cfg *latest.KustomizeDeploy
builds []build.Artifact
commands util.Command
shouldErr bool
forceDeploy bool
description string
cfg *latest.KustomizeDeploy
builds []build.Artifact
commands util.Command
shouldErr bool
forceDeploy bool
skipSkaffoldNamespaceOption bool
}{
{
description: "no manifest",
Expand All @@ -65,6 +66,23 @@ func TestKustomizeDeploy(t *testing.T) {
}},
forceDeploy: true,
},
{
description: "deploy success (default namespace)",
cfg: &latest.KustomizeDeploy{
KustomizePaths: []string{"."},
DefaultNamespace: &testNamespace2,
},
commands: testutil.
CmdRunOut("kubectl version --client -ojson", kubectlVersion112).
AndRunOut("kustomize build .", deploymentWebYAML).
AndRun("kubectl --context kubecontext --namespace testNamespace2 apply -f - --force --grace-period=0"),
builds: []build.Artifact{{
ImageName: "leeroy-web",
Tag: "leeroy-web:123",
}},
forceDeploy: true,
skipSkaffoldNamespaceOption: true,
},
{
description: "deploy success with multiple kustomizations",
cfg: &latest.KustomizeDeploy{
Expand Down Expand Up @@ -94,6 +112,11 @@ func TestKustomizeDeploy(t *testing.T) {
t.NewTempDir().
Chdir()

skaffoldNamespaceOption := ""
if !test.skipSkaffoldNamespaceOption {
skaffoldNamespaceOption = testNamespace
}

k := NewKustomizeDeployer(&runcontext.RunContext{
WorkingDir: ".",
Cfg: latest.Pipeline{
Expand All @@ -105,7 +128,7 @@ func TestKustomizeDeploy(t *testing.T) {
},
KubeContext: testKubeContext,
Opts: config.SkaffoldOptions{
Namespace: testNamespace,
Namespace: skaffoldNamespaceOption,
Force: test.forceDeploy,
},
})
Expand Down
15 changes: 15 additions & 0 deletions pkg/skaffold/kubectl/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ func NewFromRunContext(runCtx *runcontext.RunContext) *CLI {
}
}

// NewFromRunContextAndDefaultNamespace creates a new kubectl CLI whereby the namespace from
// command line / environment variable takes precedence over "default namespace" defined in
// configuration
func NewFromRunContextAndDefaultNamespace(runCtx *runcontext.RunContext, defaultNamespace string) *CLI {
ns := defaultNamespace
if runCtx.Opts.Namespace != "" {
ns = runCtx.Opts.Namespace
}
return &CLI{
KubeContext: runCtx.KubeContext,
KubeConfig: runCtx.Opts.KubeConfig,
Namespace: ns,
}
}

// Command creates the underlying exec.CommandContext. This allows low-level control of the executed command.
func (c *CLI) Command(ctx context.Context, command string, arg ...string) *exec.Cmd {
args := c.args(command, "", arg...)
Expand Down
6 changes: 6 additions & 0 deletions pkg/skaffold/schema/latest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ type KubectlDeploy struct {

// Flags are additional flags passed to `kubectl`.
Flags KubectlFlags `yaml:"flags,omitempty"`

// DefaultNamespace is the default namespace passed to kubectl on deployment if no other override is given.
DefaultNamespace *string `yaml:"defaultNamespace,omitempty"`
}

// KubectlFlags are additional flags passed on the command
Expand Down Expand Up @@ -492,6 +495,9 @@ type KustomizeDeploy struct {

// BuildArgs are additional args passed to `kustomize build`.
BuildArgs []string `yaml:"buildArgs,omitempty"`

// DefaultNamespace is the default namespace passed to kubectl on deployment if no other override is given.
DefaultNamespace *string `yaml:"defaultNamespace,omitempty"`
}

// HelmRelease describes a helm release to be deployed.
Expand Down

0 comments on commit 66c1fa8

Please sign in to comment.