diff --git a/.drone.yml b/.drone.yml index be5e74c..4c3548f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -22,7 +22,7 @@ slack_config: &slack_config image: plugins/slack pull: if-not-exists settings: - channel: dv-notifications + channel: dv-cicd environment: SLACK_WEBHOOK: from_secret: slack_webhook diff --git a/DOCS.md b/DOCS.md index 887354f..a73d489 100644 --- a/DOCS.md +++ b/DOCS.md @@ -154,6 +154,30 @@ steps: # ... ``` +### `namespace` + +_**type**_ `string` + +_**default**_ `''` + +_**description**_ name of Kubernetes Namespace where manifests will be applied + +_**notes**_ if not specified, resources will be applied to `default` Namespace; if specified and [`create_namespace`](#create_namespace) is set to `false`, the Namespace resource must already exist within the cluster + +_**example**_ + +```yaml +# .drone.yml +--- +pipeline: + # ... + deploy: + image: nytimes/drone-gke + cluster: prod + namespace: petstore + # ... +``` + ### `template` _**type**_ `string` @@ -511,6 +535,30 @@ steps: # ... ``` +### `create_namespace` + +_**type**_ `bool` + +_**default**_ `true` + +_**description**_ automatically create a Namespace resource when a [`namespace`](#namespace) value is specified + +_**notes**_ depends on non-empty `namespace` value; the resource will _always_ be applied to the cluster _prior to_ any resources included in [`template`](#template) / [`secret_template`](#secret_template); may modify any existing Namespace resource configuration; the automatically created Namespace resource is not configurable (see [source](https://github.com/nytimes/drone-gke/blob/2909135b2dce136aa5095d609d91b0963fbb4697/main.go#L51-L54) for more details); + +_**example**_ + +```yaml +# .drone.yml +--- +pipeline: + # ... + deploy: + image: nytimes/drone-gke + namespace: petstore + create_namespace: false + # ... +``` + ## Service Account Credentials `drone-gke` requires a Google service account and uses its [JSON credential file][service-account] to authenticate. diff --git a/Makefile b/Makefile index 38325df..67fed33 100644 --- a/Makefile +++ b/Makefile @@ -143,7 +143,7 @@ $(coverage_name) : export GO111MODULE ?= on $(coverage_name) : export GOPROXY ?= https://proxy.golang.org # test binary -$(coverage_name) : $(binary_name) +$(coverage_name) : $(binary_name) dump_test.go exec_test.go main_test.go @$(go) test -cover -vet all -coverprofile=$@ .PHONY : test-coverage diff --git a/main.go b/main.go index 5b34604..9fecfee 100644 --- a/main.go +++ b/main.go @@ -106,6 +106,12 @@ func getAppFlags() []cli.Flag { Usage: "Kubernetes namespace to operate in", EnvVars: []string{"PLUGIN_NAMESPACE"}, }, + &cli.BoolFlag{ + Name: "create-namespace", + Usage: "automatically create a Namespace resource when a 'namespace' value is specified", + EnvVars: []string{"PLUGIN_CREATE_NAMESPACE"}, + Value: true, + }, &cli.StringFlag{ Name: "kube-template", Usage: "template for Kubernetes resources, e.g. Deployments", @@ -710,6 +716,10 @@ func setNamespace(c *cli.Context, project string, runner Runner) error { return fmt.Errorf("Error: %s\n", err) } + if !c.Bool("create-namespace") { + return nil + } + // Write the namespace manifest to a tmp file for application. resource := fmt.Sprintf(nsTemplate, namespace) diff --git a/main_test.go b/main_test.go index 87a977e..2a45bfc 100644 --- a/main_test.go +++ b/main_test.go @@ -447,6 +447,7 @@ func TestSetNamespace(t *testing.T) { set.String("cluster", "cluster-0", "") set.String("namespace", "test-ns", "") set.Bool("dry-run", false, "") + set.Bool("create-namespace", true, "") c := cli.NewContext(nil, set, nil) testRunner := new(MockedRunner) @@ -462,6 +463,7 @@ func TestSetNamespace(t *testing.T) { set.String("cluster", "regional-cluster", "") set.String("namespace", "test-ns", "") set.Bool("dry-run", false, "") + set.Bool("create-namespace", true, "") c = cli.NewContext(nil, set, nil) testRunner = new(MockedRunner) @@ -481,6 +483,7 @@ func TestSetNamespace(t *testing.T) { set.String("cluster", "cluster-0", "") set.String("namespace", "Feature/1892-TEST-NS", "") set.Bool("dry-run", true, "") + set.Bool("create-namespace", true, "") c = cli.NewContext(nil, set, nil) testRunner = new(MockedRunner) @@ -489,6 +492,21 @@ func TestSetNamespace(t *testing.T) { err = setNamespace(c, "test-project", testRunner) testRunner.AssertExpectations(t) assert.NoError(t, err) + + // Opt-out of auto namespace creation + set = flag.NewFlagSet("no-create-namespace-set", 0) + set.String("zone", "us-east1-b", "") + set.String("cluster", "cluster-0", "") + set.String("namespace", "Feature/1892-TEST-NS", "") + set.Bool("dry-run", false, "") + set.Bool("create-namespace", false, "") + c = cli.NewContext(nil, set, nil) + + testRunner = new(MockedRunner) + testRunner.On("Run", []string{"kubectl", "config", "set-context", "gke_test-project_us-east1-b_cluster-0", "--namespace", "feature-1892-test-ns"}).Return(nil) + err = setNamespace(c, "test-project", testRunner) + testRunner.AssertExpectations(t) + assert.NoError(t, err) } func TestApplyManifests(t *testing.T) {