added code to manage secrets
This commit is contained in:
parent
b9037b9d7c
commit
f3709922b3
17 changed files with 435 additions and 24 deletions
23
api/build.go
23
api/build.go
|
@ -35,7 +35,7 @@ func init() {
|
|||
}
|
||||
droneSec = fmt.Sprintf("%s.sec", strings.TrimSuffix(droneYml, filepath.Ext(droneYml)))
|
||||
if os.Getenv("CANARY") == "true" {
|
||||
droneSec = fmt.Sprintf("%s.sig", strings.TrimSuffix(droneYml, filepath.Ext(droneYml)))
|
||||
droneSec = fmt.Sprintf("%s.sig", droneYml)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,7 +291,10 @@ func PostBuild(c *gin.Context) {
|
|||
// get the previous build so that we can send
|
||||
// on status change notifications
|
||||
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
||||
secs, _ := store.GetSecretList(c, repo)
|
||||
secs, err := store.GetSecretList(c, repo)
|
||||
if err != nil {
|
||||
log.Errorf("Error getting secrets for %s#%d. %s", repo.FullName, build.Number, err)
|
||||
}
|
||||
|
||||
// IMPORTANT. PLEASE READ
|
||||
//
|
||||
|
@ -305,14 +308,24 @@ func PostBuild(c *gin.Context) {
|
|||
var verified bool
|
||||
|
||||
signature, err := jose.ParseSigned(string(sec))
|
||||
if err == nil && len(sec) != 0 {
|
||||
if err != nil {
|
||||
log.Debugf("cannot parse .drone.yml.sig file. %s", err)
|
||||
} else if len(sec) == 0 {
|
||||
log.Debugf("cannot parse .drone.yml.sig file. empty file")
|
||||
} else {
|
||||
signed = true
|
||||
output, err := signature.Verify(repo.Hash)
|
||||
if err == nil && string(output) == string(raw) {
|
||||
output, err := signature.Verify([]byte(repo.Hash))
|
||||
if err != nil {
|
||||
log.Debugf("cannot verify .drone.yml.sig file. %s", err)
|
||||
} else if string(output) != string(raw) {
|
||||
log.Debugf("cannot verify .drone.yml.sig file. no match. %q <> %q", string(output), string(raw))
|
||||
} else {
|
||||
verified = true
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf(".drone.yml is signed=%v and verified=%v", signed, verified)
|
||||
|
||||
bus.Publish(c, bus.NewBuildEvent(bus.Enqueued, repo, build))
|
||||
for _, job := range jobs {
|
||||
queue.Publish(c, &queue.Work{
|
||||
|
|
|
@ -3,11 +3,21 @@ package client
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/drone/drone/queue"
|
||||
)
|
||||
|
||||
// Client is used to communicate with a Drone server.
|
||||
type Client interface {
|
||||
// Sign returns a cryptographic signature for the input string.
|
||||
Sign(string, string, []byte) ([]byte, error)
|
||||
|
||||
// SecretPost create or updates a repository secret.
|
||||
SecretPost(string, string, *model.Secret) error
|
||||
|
||||
// SecretDel deletes a named repository secret.
|
||||
SecretDel(string, string, string) error
|
||||
|
||||
// Pull pulls work from the server queue.
|
||||
Pull(os, arch string) (*queue.Work, error)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -22,6 +23,24 @@ const (
|
|||
pathWait = "%s/api/queue/wait/%d"
|
||||
pathStream = "%s/api/queue/stream/%d"
|
||||
pathPush = "%s/api/queue/status/%d"
|
||||
|
||||
pathSelf = "%s/api/user"
|
||||
pathFeed = "%s/api/user/feed"
|
||||
pathRepos = "%s/api/user/repos"
|
||||
pathRepo = "%s/api/repos/%s/%s"
|
||||
pathEncrypt = "%s/api/repos/%s/%s/encrypt"
|
||||
pathBuilds = "%s/api/repos/%s/%s/builds"
|
||||
pathBuild = "%s/api/repos/%s/%s/builds/%v"
|
||||
pathJob = "%s/api/repos/%s/%s/builds/%d/%d"
|
||||
pathLog = "%s/api/repos/%s/%s/logs/%d/%d"
|
||||
pathKey = "%s/api/repos/%s/%s/key"
|
||||
pathSign = "%s/api/repos/%s/%s/sign"
|
||||
pathSecrets = "%s/api/repos/%s/%s/secrets"
|
||||
pathSecret = "%s/api/repos/%s/%s/secrets/%s"
|
||||
pathNodes = "%s/api/nodes"
|
||||
pathNode = "%s/api/nodes/%d"
|
||||
pathUsers = "%s/api/users"
|
||||
pathUser = "%s/api/users/%s"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
|
@ -34,14 +53,50 @@ func NewClient(uri string) Client {
|
|||
return &client{http.DefaultClient, uri}
|
||||
}
|
||||
|
||||
// NewClientToken returns a client at the specified url that
|
||||
// authenticates all outbound requests with the given token.
|
||||
// NewClientToken returns a client at the specified url that authenticates all
|
||||
// outbound requests with the given token.
|
||||
func NewClientToken(uri, token string) Client {
|
||||
config := new(oauth2.Config)
|
||||
auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
|
||||
return &client{auther, uri}
|
||||
}
|
||||
|
||||
// NewClientTokenTLS returns a client at the specified url that authenticates
|
||||
// all outbound requests with the given token and tls.Config if provided.
|
||||
func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
|
||||
config := new(oauth2.Config)
|
||||
auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
|
||||
if c != nil {
|
||||
if trans, ok := auther.Transport.(*oauth2.Transport); ok {
|
||||
trans.Base = &http.Transport{TLSClientConfig: c}
|
||||
}
|
||||
}
|
||||
return &client{auther, uri}
|
||||
}
|
||||
|
||||
// SecretPost create or updates a repository secret.
|
||||
func (c *client) SecretPost(owner, name string, secret *model.Secret) error {
|
||||
uri := fmt.Sprintf(pathSecrets, c.base, owner, name)
|
||||
return c.post(uri, secret, nil)
|
||||
}
|
||||
|
||||
// SecretDel deletes a named repository secret.
|
||||
func (c *client) SecretDel(owner, name, secret string) error {
|
||||
uri := fmt.Sprintf(pathSecret, c.base, owner, name, secret)
|
||||
return c.delete(uri)
|
||||
}
|
||||
|
||||
// Sign returns a cryptographic signature for the input string.
|
||||
func (c *client) Sign(owner, name string, in []byte) ([]byte, error) {
|
||||
uri := fmt.Sprintf(pathSign, c.base, owner, name)
|
||||
rc, err := stream(c.client, uri, "POST", in, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
return ioutil.ReadAll(rc)
|
||||
}
|
||||
|
||||
// Pull pulls work from the server queue.
|
||||
func (c *client) Pull(os, arch string) (*queue.Work, error) {
|
||||
out := new(queue.Work)
|
||||
|
|
61
client/http.go
Normal file
61
client/http.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// helper function to stream an http request
|
||||
func stream(client *http.Client, rawurl, method string, in, out interface{}) (io.ReadCloser, error) {
|
||||
uri, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if we are posting or putting data, we need to
|
||||
// write it to the body of the request.
|
||||
var buf io.ReadWriter
|
||||
if in == nil {
|
||||
// nothing
|
||||
} else if rw, ok := in.(io.ReadWriter); ok {
|
||||
buf = rw
|
||||
} else if b, ok := in.([]byte); ok {
|
||||
buf = new(bytes.Buffer)
|
||||
buf.Write(b)
|
||||
} else {
|
||||
buf = new(bytes.Buffer)
|
||||
err := json.NewEncoder(buf).Encode(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// creates a new http request to bitbucket.
|
||||
req, err := http.NewRequest(method, uri.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in == nil {
|
||||
// nothing
|
||||
} else if _, ok := in.(io.ReadWriter); ok {
|
||||
req.Header.Set("Content-Type", "plain/text")
|
||||
} else {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode > http.StatusPartialContent {
|
||||
defer resp.Body.Close()
|
||||
out, _ := ioutil.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf(string(out))
|
||||
}
|
||||
return resp.Body, nil
|
||||
}
|
|
@ -83,7 +83,16 @@ var AgentCmd = cli.Command{
|
|||
EnvVar: "DRONE_PLUGIN_NETRC",
|
||||
Name: "netrc-plugin",
|
||||
Usage: "plugins that receive the netrc file",
|
||||
Value: &cli.StringSlice{"git", "hg"},
|
||||
Value: &cli.StringSlice{
|
||||
"git",
|
||||
"git:*",
|
||||
"hg",
|
||||
"hg:*",
|
||||
"plugins/hg",
|
||||
"plugins/hg:*",
|
||||
"plugins/git",
|
||||
"plugins/git:*",
|
||||
},
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
EnvVar: "DRONE_PLUGIN_PRIVILEGED",
|
||||
|
|
|
@ -66,25 +66,29 @@ func (r *pipeline) run() error {
|
|||
secrets = append(secrets, &model.Secret{
|
||||
Name: "DRONE_NETRC_USERNAME",
|
||||
Value: w.Netrc.Login,
|
||||
Images: []string{"git", "hg"}, // TODO(bradrydzewski) use the command line parameters here
|
||||
Images: r.config.netrc, // TODO(bradrydzewski) use the command line parameters here
|
||||
Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag},
|
||||
})
|
||||
secrets = append(secrets, &model.Secret{
|
||||
Name: "DRONE_NETRC_PASSWORD",
|
||||
Value: w.Netrc.Password,
|
||||
Images: []string{"git", "hg"},
|
||||
Images: r.config.netrc,
|
||||
Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag},
|
||||
})
|
||||
secrets = append(secrets, &model.Secret{
|
||||
Name: "DRONE_NETRC_MACHINE",
|
||||
Value: w.Netrc.Machine,
|
||||
Images: []string{"git", "hg"},
|
||||
Images: r.config.netrc,
|
||||
Events: []string{model.EventDeploy, model.EventPull, model.EventPush, model.EventTag},
|
||||
})
|
||||
}
|
||||
|
||||
for _, secret := range secrets {
|
||||
fmt.Printf("SECRET %s %s\n", secret.Name, secret.Value)
|
||||
}
|
||||
|
||||
trans := []compiler.Transform{
|
||||
builtin.NewCloneOp("plugins/git:latest", true),
|
||||
builtin.NewCloneOp("git", true),
|
||||
builtin.NewCacheOp(
|
||||
"plugins/cache:latest",
|
||||
"/var/lib/drone/cache/"+w.Repo.FullName,
|
||||
|
|
|
@ -19,10 +19,25 @@ func main2() {
|
|||
app.Name = "drone"
|
||||
app.Version = version.Version
|
||||
app.Usage = "command line utility"
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "t, token",
|
||||
Value: "",
|
||||
Usage: "server auth token",
|
||||
EnvVar: "DRONE_TOKEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "s, server",
|
||||
Value: "",
|
||||
Usage: "server location",
|
||||
EnvVar: "DRONE_SERVER",
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{
|
||||
agent.AgentCmd,
|
||||
server.ServeCmd,
|
||||
SignCmd,
|
||||
SecretCmd,
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
|
|
104
drone/secret.go
Normal file
104
drone/secret.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
// SecretCmd is the exported command for managing secrets.
|
||||
var SecretCmd = cli.Command{
|
||||
Name: "secret",
|
||||
Usage: "manage secrets",
|
||||
Subcommands: []cli.Command{
|
||||
// Secret Add
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "add a secret",
|
||||
ArgsUsage: "[repo] [key] [value]",
|
||||
UsageText: "foo",
|
||||
Action: func(c *cli.Context) {
|
||||
if err := secretAdd(c); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "inject the secret for these event types",
|
||||
Value: &cli.StringSlice{
|
||||
model.EventPush,
|
||||
model.EventTag,
|
||||
model.EventDeploy,
|
||||
},
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "inject the secret for these image types",
|
||||
Value: &cli.StringSlice{},
|
||||
},
|
||||
},
|
||||
},
|
||||
// Secret Delete
|
||||
{
|
||||
Name: "rm",
|
||||
Usage: "remove a secret",
|
||||
Action: func(c *cli.Context) {
|
||||
if err := secretDel(c); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretAdd(c *cli.Context) error {
|
||||
|
||||
repo := c.Args().First()
|
||||
owner, name, err := parseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tail := c.Args().Tail()
|
||||
if len(tail) != 2 {
|
||||
cli.ShowSubcommandHelp(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
secret := &model.Secret{}
|
||||
secret.Name = tail[0]
|
||||
secret.Value = tail[1]
|
||||
secret.Images = c.StringSlice("image")
|
||||
secret.Events = c.StringSlice("event")
|
||||
|
||||
if len(secret.Images) == 0 {
|
||||
return fmt.Errorf("Please specify the --image parameter")
|
||||
}
|
||||
|
||||
client, err := newClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.SecretPost(owner, name, secret)
|
||||
}
|
||||
|
||||
func secretDel(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := parseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
secret := c.Args().Get(1)
|
||||
|
||||
client, err := newClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.SecretDel(owner, name, secret)
|
||||
}
|
56
drone/sign.go
Normal file
56
drone/sign.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
// SignCmd is the exported command for signing the yaml.
|
||||
var SignCmd = cli.Command{
|
||||
Name: "sign",
|
||||
Usage: "creates a secure yaml file",
|
||||
Action: func(c *cli.Context) {
|
||||
if err := sign(c); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "in",
|
||||
Usage: "input file",
|
||||
Value: ".drone.yml",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "out",
|
||||
Usage: "output file signature",
|
||||
Value: ".drone.yml.sig",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func sign(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := parseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
in, err := readInput(c.String("in"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := newClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sig, err := client.Sign(owner, name, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(c.String("out"), sig, 0664)
|
||||
}
|
53
drone/util.go
Normal file
53
drone/util.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone/client"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/jackspirou/syscerts"
|
||||
)
|
||||
|
||||
func newClient(c *cli.Context) (client.Client, error) {
|
||||
var token = c.GlobalString("token")
|
||||
var server = c.GlobalString("server")
|
||||
|
||||
// if no server url is provided we can default
|
||||
// to the hosted Drone service.
|
||||
if len(server) == 0 {
|
||||
return nil, fmt.Errorf("Error: you must provide the Drone server address.")
|
||||
}
|
||||
if len(token) == 0 {
|
||||
return nil, fmt.Errorf("Error: you must provide your Drone access token.")
|
||||
}
|
||||
|
||||
// attempt to find system CA certs
|
||||
certs := syscerts.SystemRootsPool()
|
||||
tlsConfig := &tls.Config{RootCAs: certs}
|
||||
|
||||
// create the drone client with TLS options
|
||||
return client.NewClientTokenTLS(server, token, tlsConfig), nil
|
||||
}
|
||||
|
||||
func parseRepo(str string) (user, repo string, err error) {
|
||||
var parts = strings.Split(str, "/")
|
||||
if len(parts) != 2 {
|
||||
err = fmt.Errorf("Error: Invalid or missing repository. eg octocat/hello-world.")
|
||||
return
|
||||
}
|
||||
user = parts[0]
|
||||
repo = parts[1]
|
||||
return
|
||||
}
|
||||
|
||||
func readInput(in string) ([]byte, error) {
|
||||
if in == "-" {
|
||||
return ioutil.ReadAll(os.Stdin)
|
||||
}
|
||||
return ioutil.ReadFile(in)
|
||||
}
|
|
@ -79,7 +79,7 @@ func argsToEnv(from map[string]interface{}, to map[string]string) error {
|
|||
} else {
|
||||
out, err = json.YAMLToJSON(out)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
// return err TODO(bradrydzewski) unit test coverage for possible errors
|
||||
}
|
||||
to[k] = string(out)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ type Work struct {
|
|||
Netrc *model.Netrc `json:"netrc"`
|
||||
Keys *model.Key `json:"keys"`
|
||||
System *model.System `json:"system"`
|
||||
Secrets []*model.Secret `json:"secret"`
|
||||
Secrets []*model.Secret `json:"secrets"`
|
||||
User *model.User `json:"user"`
|
||||
}
|
||||
|
|
|
@ -33,10 +33,7 @@ func TestRepos(t *testing.T) {
|
|||
err1 := s.CreateRepo(&repo)
|
||||
err2 := s.UpdateRepo(&repo)
|
||||
getrepo, err3 := s.GetRepo(repo.ID)
|
||||
if err3 != nil {
|
||||
println("Get Repo Error")
|
||||
println(err3.Error())
|
||||
}
|
||||
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
|
|
7
stream/reader_test.go
Normal file
7
stream/reader_test.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package stream
|
||||
|
||||
import "testing"
|
||||
|
||||
func TetsReader(t *testing.T) {
|
||||
t.Skip() //TODO(bradrydzewski) implement reader tests
|
||||
}
|
7
stream/stream_impl_test.go
Normal file
7
stream/stream_impl_test.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package stream
|
||||
|
||||
import "testing"
|
||||
|
||||
func TetsStream(t *testing.T) {
|
||||
t.Skip() //TODO(bradrydzewski) implement stream tests
|
||||
}
|
7
stream/writer_test.go
Normal file
7
stream/writer_test.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package stream
|
||||
|
||||
import "testing"
|
||||
|
||||
func TetsWriter(t *testing.T) {
|
||||
t.Skip() //TODO(bradrydzewski) implement writer tests
|
||||
}
|
23
web/hook.go
23
web/hook.go
|
@ -33,7 +33,7 @@ func init() {
|
|||
}
|
||||
droneSec = fmt.Sprintf("%s.sec", strings.TrimSuffix(droneYml, filepath.Ext(droneYml)))
|
||||
if os.Getenv("CANARY") == "true" {
|
||||
droneSec = fmt.Sprintf("%s.sig", strings.TrimSuffix(droneYml, filepath.Ext(droneYml)))
|
||||
droneSec = fmt.Sprintf("%s.sig", droneYml)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,10 @@ func PostHook(c *gin.Context) {
|
|||
// get the previous build so that we can send
|
||||
// on status change notifications
|
||||
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
||||
secs, _ := store.GetSecretList(c, repo)
|
||||
secs, err := store.GetSecretList(c, repo)
|
||||
if err != nil {
|
||||
log.Errorf("Error getting secrets for %s#%d. %s", repo.FullName, build.Number, err)
|
||||
}
|
||||
|
||||
// IMPORTANT. PLEASE READ
|
||||
//
|
||||
|
@ -223,14 +226,24 @@ func PostHook(c *gin.Context) {
|
|||
var verified bool
|
||||
|
||||
signature, err := jose.ParseSigned(string(sec))
|
||||
if err == nil && len(sec) != 0 {
|
||||
if err != nil {
|
||||
log.Debugf("cannot parse .drone.yml.sig file. %s", err)
|
||||
} else if len(sec) == 0 {
|
||||
log.Debugf("cannot parse .drone.yml.sig file. empty file")
|
||||
} else {
|
||||
signed = true
|
||||
output, err := signature.Verify(repo.Hash)
|
||||
if err == nil && string(output) == string(raw) {
|
||||
output, err := signature.Verify([]byte(repo.Hash))
|
||||
if err != nil {
|
||||
log.Debugf("cannot verify .drone.yml.sig file. %s", err)
|
||||
} else if string(output) != string(raw) {
|
||||
log.Debugf("cannot verify .drone.yml.sig file. no match")
|
||||
} else {
|
||||
verified = true
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf(".drone.yml is signed=%v and verified=%v", signed, verified)
|
||||
|
||||
bus.Publish(c, bus.NewBuildEvent(bus.Enqueued, repo, build))
|
||||
for _, job := range jobs {
|
||||
queue.Publish(c, &queue.Work{
|
||||
|
|
Loading…
Reference in a new issue