Skip to content

Commit

Permalink
Fix skipping templates for Drone 1.x (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonglil authored Apr 28, 2020
1 parent dba5426 commit c8a8687
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 9 deletions.
82 changes: 80 additions & 2 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ _**default**_ `'.kube.yml'`

_**description**_ path to Kubernetes manifest template

_**notes**_ rendered using the Go [`text/template`](https://golang.org/pkg/text/template/) package
_**notes**_ rendered using the Go [`text/template`](https://golang.org/pkg/text/template/) package.
If the file does not exist, set `skip_template` to `true`.

_**example**_

Expand Down Expand Up @@ -219,6 +220,44 @@ pipeline:
# ...
```

### `skip_template`

_**type**_ `bool`

_**default**_ `false`

_**description**_ parse and apply the Kubernetes manifest template

_**notes**_ turn off the use of the template, regardless if the file exists or not

_**example**_

```yaml
# .drone.yml

# Drone 1.0+
---
kind: pipeline
# ...
steps:
- name: deploy-gke
image: nytimes/drone-gke
settings:
template: k8s/app.yaml
skip_template: true
# ...

# Drone 0.8
---
pipeline:
# ...
deploy:
image: nytimes/drone-gke
template: k8s/app.yaml
skip_template: true
# ...
```

### `secret_template`

_**type**_ `string`
Expand All @@ -227,7 +266,44 @@ _**default**_ `'.kube.sec.yml'`

_**description**_ path to Kubernetes [_Secret_ resource](http://kubernetes.io/docs/user-guide/secrets/) manifest template

_**notes**_ rendered using the Go [`text/template`](https://golang.org/pkg/text/template/) package
_**notes**_ rendered using the Go [`text/template`](https://golang.org/pkg/text/template/) package.
If the file does not exist, set `skip_secret_template` to `true`.

_**example**_

```yaml
# .drone.yml

# Drone 1.0+
---
kind: pipeline
# ...
steps:
- name: deploy-gke
image: nytimes/drone-gke
settings:
secret_template: my-templates/secrets.yaml
# ...

# Drone 0.8
---
pipeline:
# ...
deploy:
image: nytimes/drone-gke
secret_template: my-templates/secrets.yaml
# ...
```

### `skip_secret_template`

_**type**_ `bool`

_**default**_ `false`

_**description**_ parse and apply the Kubernetes _Secret_ resource manifest template

_**notes**_ turn off the use of the template, regardless if the file exists or not

_**example**_

Expand All @@ -243,6 +319,7 @@ steps:
image: nytimes/drone-gke
settings:
secret_template: my-templates/secrets.yaml
skip_secret_template: true
# ...

# Drone 0.8
Expand All @@ -252,6 +329,7 @@ pipeline:
deploy:
image: nytimes/drone-gke
secret_template: my-templates/secrets.yaml
skip_secret_template: true
# ...
```

Expand Down
49 changes: 45 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,26 @@ func getAppFlags() []cli.Flag {
},
&cli.StringFlag{
Name: "kube-template",
Usage: "optional - template for Kubernetes resources, e.g. deployments",
Usage: "template for Kubernetes resources, e.g. deployments",
EnvVars: []string{"PLUGIN_TEMPLATE"},
Value: ".kube.yml",
},
&cli.BoolFlag{
Name: "skip-template",
Usage: "do not parse or apply the Kubernetes template",
EnvVars: []string{"PLUGIN_SKIP_TEMPLATE"},
},
&cli.StringFlag{
Name: "secret-template",
Usage: "optional - template for Kubernetes Secret resources",
Usage: "template for Kubernetes Secret resources",
EnvVars: []string{"PLUGIN_SECRET_TEMPLATE"},
Value: ".kube.sec.yml",
},
&cli.BoolFlag{
Name: "skip-secret-template",
Usage: "do not parse or apply the Kubernetes Secret template",
EnvVars: []string{"PLUGIN_SKIP_SECRET_TEMPLATE"},
},
&cli.StringFlag{
Name: "vars",
Usage: "variables to use while templating manifests",
Expand Down Expand Up @@ -204,7 +214,13 @@ func run(c *cli.Context) error {
}
}

// Use custom kubectl version if provided
// Parse skipping template processing.
err := parseSkips(c)
if err != nil {
return err
}

// Use custom kubectl version if provided.
kubectlVersion := c.String("kubectl-version")
if kubectlVersion != "" {
kubectlCmd = fmt.Sprintf("%s.%s", kubectlCmdName, kubectlVersion)
Expand Down Expand Up @@ -351,6 +367,31 @@ func getProjectFromToken(j string) string {
return t.ProjectID
}

// parseSkips determines which templates will be processed.
// Prior in Drone 0.8 we allowed setting template filenames to an empty string "" to skip processing them.
// As of Drone 1.7, env vars that have an empty string as the value are dropped.
// So we need to use and check the new set of flags to determine if the user wants to skip processing a template file.
func parseSkips(c *cli.Context) error {
if c.Bool("skip-template") {
log("Warning: skipping kube-template because it was set to be ignored\n")
if err := c.Set("kube-template", ""); err != nil {
return err
}
}
if c.Bool("skip-secret-template") {
log("Warning: skipping secret-template because it was set to be ignored\n")
if err := c.Set("secret-template", ""); err != nil {
return err
}
}

if c.Bool("skip-template") && c.Bool("skip-secret-template") {
return fmt.Errorf("Error: skipping both templates ends the plugin execution\n")
}

return nil
}

// parseVars parses vars (in JSON) and returns a map
func parseVars(c *cli.Context) (map[string]interface{}, error) {
// Parse variables.
Expand Down Expand Up @@ -522,7 +563,7 @@ func renderTemplates(c *cli.Context, templateData map[string]interface{}, secret
return nil, fmt.Errorf("Error finding template: %s\n", err)
}

log("Warning: skipping optional template %s because it was not found\n", t)
log("Warning: skipping optional secret template %s because it was not found\n", t)
continue
}

Expand Down
50 changes: 47 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,50 @@ func TestRenderTemplates(t *testing.T) {
assert.Error(t, err)
}

func TestParseSkips(t *testing.T) {
kubeTemplatePath := "/tmp/drone-gke-tests/.kube.yml"
secretTemplatePath := "/tmp/drone-gke-tests/.kube.sec.yml"

// Test no skip
set := flag.NewFlagSet("test-set", 0)
set.String("kube-template", kubeTemplatePath, "")
set.String("secret-template", secretTemplatePath, "")
c := cli.NewContext(nil, set, nil)
err := parseSkips(c)
assert.NoError(t, err)
assert.Equal(t, kubeTemplatePath, c.String("kube-template"))
assert.Equal(t, secretTemplatePath, c.String("secret-template"))

// Test skipping both
set.Bool("skip-template", true, "")
set.Bool("skip-secret-template", true, "")
c = cli.NewContext(nil, set, nil)
err = parseSkips(c)
assert.Error(t, err)

// Test skip template
kubeSet := flag.NewFlagSet("kube-set", 0)
kubeSet.String("kube-template", kubeTemplatePath, "")
kubeSet.String("secret-template", secretTemplatePath, "")
kubeSet.Bool("skip-template", true, "")
c = cli.NewContext(nil, kubeSet, nil)
err = parseSkips(c)
assert.NoError(t, err)
assert.Empty(t, c.String("kube-template"))
assert.Equal(t, secretTemplatePath, c.String("secret-template"))

// Test skip template
secretSet := flag.NewFlagSet("secret-set", 0)
secretSet.String("kube-template", kubeTemplatePath, "")
secretSet.String("secret-template", secretTemplatePath, "")
secretSet.Bool("skip-secret-template", true, "")
c = cli.NewContext(nil, secretSet, nil)
err = parseSkips(c)
assert.NoError(t, err)
assert.Equal(t, kubeTemplatePath, c.String("kube-template"))
assert.Empty(t, c.String("secret-template"))
}

func TestPrintKubectlVersion(t *testing.T) {
testRunner := new(MockedRunner)
testRunner.On("Run", []string{"kubectl", "version"}).Return(nil)
Expand Down Expand Up @@ -570,8 +614,8 @@ func TestTokenParamPrecedence(t *testing.T) {
name: "both-and-plugin-token-wins",
envToken: "token456",
envPluginToken: "token123",
expectedOk: true,
expectedToken: "token123",
expectedOk: true,
expectedToken: "token123",
},
{
name: "missing-token",
Expand All @@ -584,7 +628,7 @@ func TestTokenParamPrecedence(t *testing.T) {
} {
t.Run(tst.name, func(t *testing.T) {
os.Clearenv()

os.Setenv("PLUGIN_REGION", "region-123")
os.Setenv("PLUGIN_CLUSTER", "cluster-123")

Expand Down

0 comments on commit c8a8687

Please sign in to comment.