From 6529e095a8a40cbf240711e37362d94d70335c23 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Thu, 21 Apr 2016 01:18:20 -0700 Subject: [PATCH] enables cloning private repos --- drone/agent/agent.go | 22 +++++++++++++++++----- drone/agent/exec.go | 23 ++++++++++++++++++++++- model/secret.go | 22 ++++++++++++---------- model/secret_test.go | 22 ++++++++++++++++++++++ yaml/checksum/checksum.go | 6 ++---- yaml/checksum/checksum_test.go | 4 ++-- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/drone/agent/agent.go b/drone/agent/agent.go index 17d5e3690..2aeb43336 100644 --- a/drone/agent/agent.go +++ b/drone/agent/agent.go @@ -52,21 +52,33 @@ var AgentCmd = cli.Command{ Usage: "drone authorization token", }, cli.DurationFlag{ - EnvVar: "BACKOFF", - Name: "drone-backoff", + EnvVar: "DRONE_BACKOFF", + Name: "backoff", Usage: "drone server backoff interval", Value: time.Second * 15, }, cli.BoolFlag{ - EnvVar: "DEBUG", + EnvVar: "DRONE_DEBUG", Name: "debug", Usage: "start the agent in debug mode", }, cli.BoolFlag{ - EnvVar: "EXPERIMENTAL", + EnvVar: "DRONE_EXPERIMENTAL", Name: "experimental", Usage: "start the agent with experimental features", }, + cli.StringSliceFlag{ + EnvVar: "DRONE_NETRC_PLUGIN", + Name: "netrc-plugin", + Usage: "plugins that receive the netrc file", + Value: &cli.StringSlice{"git", "hg"}, + }, + cli.StringSliceFlag{ + EnvVar: "DRONE_PRIVILEGED_PLUGIN", + Name: "privileged-plugin", + Usage: "plugins that require privileged mode", + Value: &cli.StringSlice{"docker", "gcr", "ecr"}, + }, }, } @@ -99,7 +111,7 @@ func start(c *cli.Context) { go func() { for { if err := recoverExec(client, docker); err != nil { - dur := c.Duration("drone-backoff") + dur := c.Duration("backoff") logrus.Debugf("Attempting to reconnect in %v", dur) time.Sleep(dur) } diff --git a/drone/agent/exec.go b/drone/agent/exec.go index 60d66e5d2..16b5c98dd 100644 --- a/drone/agent/exec.go +++ b/drone/agent/exec.go @@ -47,7 +47,28 @@ func exec(client client.Client, docker dockerclient.Client) error { envs := toEnv(w) w.Yaml = expander.ExpandString(w.Yaml, envs) - w.Secrets = append(w.Secrets, &model.Secret{Name: "HEROKU_TOKEN", Value: "GODZILLA", Images: []string{"golang:1.4.2"}, Events: []string{w.Build.Event}}) + // inject the netrc file into the clone plugin if the repositroy is + // private and requires authentication. + if w.Repo.IsPrivate { + w.Secrets = append(w.Secrets, &model.Secret{ + Name: "DRONE_NETRC_USERNAME", + Value: w.Netrc.Login, + Images: []string{"git", "hg"}, // TODO(bradrydzewski) use the command line parameters here + Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag}, + }) + w.Secrets = append(w.Secrets, &model.Secret{ + Name: "DRONE_NETRC_PASSWORD", + Value: w.Netrc.Password, + Images: []string{w.Repo.Kind}, + Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag}, + }) + w.Secrets = append(w.Secrets, &model.Secret{ + Name: "DRONE_NETRC_MACHINE", + Value: w.Netrc.Machine, + Images: []string{"git", "hg"}, + Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag}, + }) + } trans := []compiler.Transform{ builtin.NewCloneOp("plugins/"+w.Repo.Kind+":latest", true), diff --git a/model/secret.go b/model/secret.go index 919dda5e7..c22e7ca54 100644 --- a/model/secret.go +++ b/model/secret.go @@ -1,5 +1,7 @@ package model +import "path/filepath" + type Secret struct { // the id for this secret. ID int64 `json:"id" meddler:"secret_id,pk"` @@ -7,12 +9,12 @@ type Secret struct { // the foreign key for this secret. RepoID int64 `json:"-" meddler:"secret_repo_id"` - // the name of the secret which will be used as the - // environment variable name at runtime. + // the name of the secret which will be used as the environment variable + // name at runtime. Name string `json:"name" meddler:"secret_name"` - // the value of the secret which will be provided to - // the runtime environment as a named environment variable. + // the value of the secret which will be provided to the runtime environment + // as a named environment variable. Value string `json:"value" meddler:"secret_value"` // the secret is restricted to this list of images. @@ -28,9 +30,9 @@ func (s *Secret) Match(image, event string) bool { } // MatchImage returns true if an image matches the restricted list. -func (s *Secret) MatchImage(want string) bool { - for _, got := range s.Images { - if want == got { +func (s *Secret) MatchImage(image string) bool { + for _, pattern := range s.Images { + if match, _ := filepath.Match(pattern, image); match { return true } } @@ -38,9 +40,9 @@ func (s *Secret) MatchImage(want string) bool { } // MatchEvent returns true if an event matches the restricted list. -func (s *Secret) MatchEvent(want string) bool { - for _, got := range s.Events { - if want == got { +func (s *Secret) MatchEvent(event string) bool { + for _, pattern := range s.Events { + if match, _ := filepath.Match(pattern, event); match { return true } } diff --git a/model/secret_test.go b/model/secret_test.go index 4e159d094..eec2b560f 100644 --- a/model/secret_test.go +++ b/model/secret_test.go @@ -21,11 +21,33 @@ func TestSecret(t *testing.T) { secret.Events = []string{"pull_request"} g.Assert(secret.MatchEvent("pull_request")).IsTrue() }) + g.It("should match image patterns", func() { + secret := Secret{} + secret.Images = []string{"golang:*"} + g.Assert(secret.MatchImage("golang:1.4.2")).IsTrue() + }) + g.It("should match any image", func() { + secret := Secret{} + secret.Images = []string{"*"} + g.Assert(secret.MatchImage("golang")).IsTrue() + }) + g.It("should match any event", func() { + secret := Secret{} + secret.Events = []string{"*"} + g.Assert(secret.MatchEvent("pull_request")).IsTrue() + }) g.It("should not match image", func() { secret := Secret{} secret.Images = []string{"golang"} g.Assert(secret.MatchImage("node")).IsFalse() }) + g.It("should not match image substring", func() { + secret := Secret{} + secret.Images = []string{"golang"} + + // image is only authorized for golang, not golang:1.4.2 + g.Assert(secret.MatchImage("golang:1.4.2")).IsFalse() + }) g.It("should not match event", func() { secret := Secret{} secret.Events = []string{"pull_request"} diff --git a/yaml/checksum/checksum.go b/yaml/checksum/checksum.go index d87c1771a..4a021a692 100644 --- a/yaml/checksum/checksum.go +++ b/yaml/checksum/checksum.go @@ -9,8 +9,8 @@ import ( "strings" ) -// Check is a calculates and verifies a file checksum. -// This supports the sha1, sha256 and sha512 values. +// Check is a calculates and verifies a file checksum. This supports the sha1, +// sha256 and sha512 values. func Check(in, checksum string) bool { hash, size, _ := split(checksum) @@ -27,8 +27,6 @@ func Check(in, checksum string) bool { return sha512sum(in) == hash case 40: return sha1sum(in) == hash - case 0: - return true // if no checksum assume valid } return false diff --git a/yaml/checksum/checksum_test.go b/yaml/checksum/checksum_test.go index 4bc82d898..9dd6925c7 100644 --- a/yaml/checksum/checksum_test.go +++ b/yaml/checksum/checksum_test.go @@ -89,9 +89,9 @@ func TestParse(t *testing.T) { g.Assert(ok).IsFalse() }) - g.It("Should return true if empty checksum", func() { + g.It("Should return false if empty checksum", func() { ok := Check("foo\n", "") - g.Assert(ok).IsTrue() + g.Assert(ok).IsFalse() }) }) }