provides a way to white-list plugins at a global config level

This commit is contained in:
Brad Rydzewski 2015-05-19 23:19:59 -07:00
parent f3c06a8fc3
commit 8c655d600d
7 changed files with 139 additions and 31 deletions

View file

@ -20,7 +20,8 @@ type Context struct {
Keys *common.Keypair `json:"keys"`
Netrc *common.Netrc `json:"netrc"`
Yaml []byte `json:"yaml"`
Env []string `json:"env"`
Env []string `json:"environment"`
Plugins []string `json:"plugins"`
Conf *common.Config `json:"-"`
infos []*dockerclient.ContainerInfo
@ -29,12 +30,19 @@ type Context struct {
func setup(c *Context) error {
var err error
var opts = parser.DefaultOpts
var opts = parser.Opts{
Network: true,
Privileged: true,
Volumes: true,
Whitelist: c.Plugins,
}
// if repository is trusted the build may specify
// custom volumes, networking and run in trusted mode.
if c.Repo.Trusted {
opts = &parser.Opts{Network: true, Privileged: true, Volumes: true}
opts.Network = true
opts.Privileged = true
opts.Volumes = true
}
// inject the matrix parameters into the yaml

View file

@ -15,7 +15,8 @@ type Work struct {
Keys *common.Keypair `json:"keypair"`
Netrc *common.Netrc `json:"netrc"`
Yaml []byte `json:"yaml"`
Env []string `json:"env"`
Env []string `json:"environment"`
Plugins []string `json:"plugins"`
}
// represents a worker that has connected

View file

@ -119,6 +119,7 @@ func (r *Runner) Run(w *queue.Work) error {
Yaml: w.Yaml,
Build: task,
Env: w.Env,
Plugins: w.Plugins,
}
in, err := json.Marshal(work)
if err != nil {

View file

@ -58,7 +58,8 @@ type work struct {
Keys *common.Keypair `json:"keys"`
Netrc *common.Netrc `json:"netrc"`
Yaml []byte `json:"yaml"`
Env []string `json:"env"`
Env []string `json:"environment"`
Plugins []string `json:"plugins"`
}
type worker struct {

View file

@ -2,6 +2,7 @@ package parser
import (
"fmt"
"path/filepath"
"strings"
common "github.com/drone/drone/pkg/types"
@ -103,3 +104,42 @@ func expectTrustedNotify(c *common.Config) error {
}
return nil
}
func LintPlugins(c *common.Config, opts *Opts) error {
if len(opts.Whitelist) == 0 {
return nil
}
var images []string
images = append(images, c.Setup.Image)
images = append(images, c.Clone.Image)
c.Clone.Image = imageName(c.Clone.Image)
for _, step := range c.Publish {
images = append(images, step.Image)
}
for _, step := range c.Deploy {
images = append(images, step.Image)
}
for _, step := range c.Notify {
images = append(images, step.Image)
}
for _, image := range images {
match := false
for _, pattern := range opts.Whitelist {
if pattern == image {
match = true
break
}
ok, err := filepath.Match(pattern, image)
if ok && err == nil {
match = true
break
}
}
if !match {
return fmt.Errorf("Cannot use un-trusted image %s", image)
}
}
return nil
}

View file

@ -90,3 +90,58 @@ func Test_Linter(t *testing.T) {
})
}
func Test_LintPlugins(t *testing.T) {
g := goblin.Goblin(t)
g.Describe("Plugin Linter", func() {
g.It("Should fail un-trusted plugin", func() {
c := &common.Config{
Setup: &common.Step{Image: "foo/baz"},
Clone: &common.Step{Image: "foo/bar"},
Notify: map[string]*common.Step{},
Deploy: map[string]*common.Step{},
Publish: map[string]*common.Step{},
}
o := &Opts{Whitelist: []string{"plugins/*"}}
g.Assert(LintPlugins(c, o) != nil).IsTrue()
})
g.It("Should pass when empty whitelist", func() {
c := &common.Config{
Setup: &common.Step{Image: "foo/baz"},
Clone: &common.Step{Image: "foo/bar"},
Notify: map[string]*common.Step{},
Deploy: map[string]*common.Step{},
Publish: map[string]*common.Step{},
}
o := &Opts{Whitelist: []string{}}
g.Assert(LintPlugins(c, o) == nil).IsTrue()
})
g.It("Should pass wildcard", func() {
c := &common.Config{
Setup: &common.Step{Image: "plugins/drone-setup"},
Clone: &common.Step{Image: "plugins/drone-build"},
Notify: map[string]*common.Step{},
Deploy: map[string]*common.Step{},
Publish: map[string]*common.Step{},
}
o := &Opts{Whitelist: []string{"plugins/*"}}
g.Assert(LintPlugins(c, o) == nil).IsTrue()
})
g.It("Should pass itemized", func() {
c := &common.Config{
Setup: &common.Step{Image: "plugins/drone-setup"},
Clone: &common.Step{Image: "plugins/drone-build"},
Notify: map[string]*common.Step{},
Deploy: map[string]*common.Step{},
Publish: map[string]*common.Step{},
}
o := &Opts{Whitelist: []string{"plugins/drone-setup", "plugins/drone-build"}}
g.Assert(LintPlugins(c, o) == nil).IsTrue()
})
})
}

View file

@ -14,12 +14,14 @@ type Opts struct {
Volumes bool
Network bool
Privileged bool
Whitelist []string
}
var DefaultOpts = &Opts{
Volumes: false,
Network: false,
Privileged: false,
Whitelist: []string{"plugins/*"},
}
// Parse parses a build matrix and returns