Skip to content

Commit

Permalink
Defaults extension (#15)
Browse files Browse the repository at this point in the history
* add defaults plugin

* update deps

* remove var

* simplify

* cleanup tests

* use pointer

* refactor cli, add config pkg

* add test

* update tests/readme

* check err

* write custom manifest encoder

* move things around

* simplify some code

* remove struct tags

* add json tags

* update .licensed.yaml

* update licensed-go image

* use struct instead of pointer

* update licensed

* user jsonpatch instead

* updates tests

* merge function

* update deps

* update images

* make tests more readable

* add desc

* use yaml encoder for encoding resources

* fix tests

* update test

* remove separator

* use nil config to skip merge when no defaults are specified
  • Loading branch information
colinhoglund authored Feb 9, 2023
1 parent adba3c0 commit 5cffae7
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 208 deletions.
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ volumes:

steps:
- name: test
image: golangci/golangci-lint:v1.42.1
image: golangci/golangci-lint:v1.51.1
volumes:
- name: cache
path: /go
commands:
- make test

- name: license-check
image: public.ecr.aws/kanopy/licensed-go:3.4.4
image: public.ecr.aws/kanopy/licensed-go:4.0.4-0.1.0
commands:
- licensed cache
- licensed status
Expand Down
11 changes: 4 additions & 7 deletions .licensed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ allowed:
- isc
reviewed:
go:
- github.com/buildkite/yaml ## apache
- github.com/drone/go-scm/**/* # bsd
- github.com/kanopy-platform/go-http-middleware/* # apache-2.0
- github.com/magiconair/properties # bsd-2-clause
- github.com/buildkite/yaml # Apache-2.0
- github.com/drone/go-scm/**/* # BSD-2-Clause-Patent
- github.com/kanopy-platform/go-http-middleware/* # Apache-2.0
- golang.org/x/**/* # bsd-style
- google.golang.org/protobuf/**/* # bsd
- gopkg.in/ini.v1 # apache-2.0
- gopkg.in/yaml.v2 # apache-2.0
- google.golang.org/protobuf/**/* # BSD-3-Clause
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.16 as build
FROM golang:1.20 as build
ARG VERSION="0.0.0"
ARG GIT_COMMIT
WORKDIR /go/src/app
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ The configuration format is as follows:
```
---
convert:
defaults:
enable: true
pipeline:
node_selector:
instancegroup: drone
tolerations:
- key: dedicated
operator: Equal
value: drone
effect: NoSchedule
pathschanged:
enable: true
```
Expand All @@ -30,6 +40,7 @@ convert:

|Plugin|Description|
|-|-|
|[defaults](./internal/plugin/convert/defaults/)|Takes Drone resource configuration as input and merges that with resources in the pipeline request. User provided values take precedence.|
|[pathschanged](https://github.com/meltwater/drone-convert-pathschanged)|Include/exclude pipelines and pipeline steps based on paths changed.|

## Testing
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile-test
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golangci/golangci-lint:v1.42.1 as cache
FROM golangci/golangci-lint:v1.51.1 as cache
ENV GOLANGCI_LINT_CACHE /root/.cache/go-build
WORKDIR $GOPATH/src/github.com/kanopy-platform/drone-extension-router

Expand Down
14 changes: 8 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ go 1.20
require (
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e
github.com/drone/drone-go v1.7.2-0.20220308165842-f9e4fe31c2af
github.com/evanphx/json-patch/v5 v5.6.0
github.com/kanopy-platform/go-http-middleware v0.1.1
github.com/kelseyhightower/envconfig v1.4.0
github.com/meltwater/drone-convert-pathschanged v1.0.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.6.1
github.com/stretchr/testify v1.8.1
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -23,14 +24,15 @@ require (
github.com/drone/go-scm v1.16.1 // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.2 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
google.golang.org/protobuf v1.27.1 // indirect
)
212 changes: 22 additions & 190 deletions go.sum

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package config

import (
"github.com/drone/drone-go/plugin/converter"
"github.com/kanopy-platform/drone-extension-router/internal/plugin/convert/defaults"
"github.com/kanopy-platform/drone-extension-router/internal/plugin/convert/pathschanged"
"github.com/kanopy-platform/drone-extension-router/pkg/manifest"
)

type (
Expand All @@ -11,9 +13,15 @@ type (
}

Convert struct {
Defaults Defaults `yaml:"defaults"`
Pathschanged Pathschanged `yaml:"pathschanged"`
}

Defaults struct {
Enable bool `yaml:"enable"`
Pipeline *manifest.Pipeline `yaml:"pipeline,omitempty"`
}

Pathschanged struct {
Enable bool `yaml:"enable"`
}
Expand All @@ -26,6 +34,10 @@ func New() *Config {
func (c *Config) EnabledConvertPlugins() []converter.Plugin {
plugins := []converter.Plugin{}

if c.Convert.Defaults.Enable {
plugins = append(plugins, defaults.New(defaults.Config{Pipeline: c.Convert.Defaults.Pipeline}))
}

if c.Convert.Pathschanged.Enable {
plugins = append(plugins, pathschanged.New())
}
Expand Down
15 changes: 14 additions & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@ import (
func TestConfig(t *testing.T) {
data := `---
convert:
defaults:
enable: true
pipeline:
node_selector:
instancegroup: drone
tolerations:
- key: dedicated
operator: Equal
value: drone
effect: NoSchedule
pathschanged:
enable: true`

c := config.New()
assert.NoError(t, yaml.Unmarshal([]byte(data), c))

enabled := c.EnabledConvertPlugins()
assert.Len(t, enabled, 1)
assert.Len(t, enabled, 2)

assert.True(t, c.Convert.Defaults.Enable)
assert.True(t, c.Convert.Pathschanged.Enable)
assert.Equal(t, "drone", c.Convert.Defaults.Pipeline.NodeSelector["instancegroup"])
assert.Equal(t, "drone", c.Convert.Defaults.Pipeline.Tolerations[0].Value)
}
72 changes: 72 additions & 0 deletions internal/plugin/convert/defaults/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package defaults

import (
"context"
"encoding/json"

"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin/converter"
jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/kanopy-platform/drone-extension-router/pkg/manifest"
)

type Config struct {
Pipeline *manifest.Pipeline `json:"pipeline,omitempty"`
}

type Defaults struct {
config Config
}

func New(c Config) *Defaults {
return &Defaults{config: c}
}

func (d *Defaults) Convert(ctx context.Context, req *converter.Request) (*drone.Config, error) {
// decode pipeline resources
resources, err := manifest.Decode(req.Config.Data)
if err != nil {
return nil, err
}

// merge defaults into user-defined resources
for _, r := range resources {
switch r.(type) {
case *manifest.Pipeline:
if d.config.Pipeline != nil {
if err := merge(d.config.Pipeline, r); err != nil {
return nil, err
}
}
}
}

// encode pipeline resources
data, err := manifest.Encode(resources)
if err != nil {
return nil, err
}

return &drone.Config{
Data: string(data),
}, nil
}

func merge(defaults, user manifest.Resource) error {
defaultBytes, err := json.Marshal(defaults)
if err != nil {
return err
}

userBytes, err := json.Marshal(user)
if err != nil {
return err
}

userBytes, err = jsonpatch.MergePatch(defaultBytes, userBytes)
if err != nil {
return err
}

return json.Unmarshal(userBytes, user)
}
151 changes: 151 additions & 0 deletions internal/plugin/convert/defaults/defaults_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package defaults_test

import (
"context"
"testing"

"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin/converter"
"github.com/kanopy-platform/drone-extension-router/internal/plugin/convert/defaults"
"github.com/kanopy-platform/drone-extension-router/pkg/manifest"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)

func TestDefaults(t *testing.T) {
tests := []struct {
desc string
config string
request string
want string
}{
{
desc: "test with empty defaults and request",
},
{
desc: "test without defaults",
request: "kind: pipeline",
want: "kind: pipeline\n",
},
{
desc: "test with defaults",
config: `
pipeline:
node_selector:
d: d
test: d
map:
d: d
test: d
list:
- test: d`,
request: `
kind: pipeline
node_selector:
r: r
test: r
map:
r: r
test: r
list:
- test: r`,
want: `kind: pipeline
node_selector:
d: d
r: r
test: r
list:
- test: r
map:
d: d
r: r
test: r
`,
},
{
desc: "test default node_selector and tolerations",
config: `
pipeline:
kind: pipeline
node_selector:
instancegroup: drone
tolerations:
- key: dedicated
operator: Equal
value: drone
effect: NoSchedule`,
request: `
kind: pipeline
node_selector:
instancegroup: batch
tolerations:
- key: dedicated
operator: Equal
value: batch
effect: NoSchedule`,
want: `kind: pipeline
node_selector:
instancegroup: batch
tolerations:
- key: dedicated
operator: Equal
value: batch
effect: NoSchedule
`,
},
{
desc: "test with multiple objects",
config: `
pipeline:
type: test`,
request: `
kind: pipeline
name: user
---
kind: fake
fake: field
---
kind: secret
name: user`,
want: `kind: pipeline
type: test
name: user
---
kind: fake
fake: field
---
kind: secret
name: user
`,
},
}

for _, test := range tests {
c := defaults.Config{}
assert.NoError(t, yaml.Unmarshal([]byte(test.config), &c), test.desc)

req := &converter.Request{Config: drone.Config{Data: test.request}}

config, err := defaults.New(c).Convert(context.TODO(), req)
assert.NoError(t, err, test.desc)

assert.Equal(t, test.want, config.Data, test.desc)
}
}

func BenchmarkConvertNil(b *testing.B) {
benchmarkConvert(b, defaults.Config{Pipeline: nil})
}

func BenchmarkConvert(b *testing.B) {
benchmarkConvert(b, defaults.Config{Pipeline: &manifest.Pipeline{}})
}

func benchmarkConvert(b *testing.B, conf defaults.Config) {
plugin := defaults.New(conf)
req := &converter.Request{Config: drone.Config{Data: "kind: pipeline"}}

for n := 0; n < b.N; n++ {
_, _ = plugin.Convert(context.TODO(), req)
}
}

0 comments on commit 5cffae7

Please sign in to comment.