commit
3cf5788f13
@ -0,0 +1,22 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang
|
||||
commands:
|
||||
- go build
|
||||
- go test ./...
|
||||
|
||||
- name: docker-build
|
||||
image: plugins/docker
|
||||
settings:
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
registry: hub.codefirst.iut.uca.fr
|
||||
repo: hub.codefirst.iut.uca.fr/thomas.bellembois/drone-secret-plugin
|
||||
username:
|
||||
from_secret: SECRET_REGISTRY_USERNAME
|
||||
password:
|
||||
from_secret: SECRET_REGISTRY_PASSWORD
|
@ -0,0 +1,2 @@
|
||||
.env
|
||||
drone-secret-plugin
|
@ -0,0 +1,7 @@
|
||||
FROM debian:bookworm
|
||||
EXPOSE 3000
|
||||
|
||||
ENV GODEBUG netdns=go
|
||||
|
||||
ADD drone-secret-plugin /bin/
|
||||
ENTRYPOINT ["/bin/drone-secret-plugin"]
|
@ -0,0 +1,2 @@
|
||||
[Polyform-Small-Business-1.0.0](https://polyformproject.org/licenses/small-business/1.0.0) OR
|
||||
[Polyform-Free-Trial-1.0.0](https://polyformproject.org/licenses/free-trial/1.0.0)
|
@ -0,0 +1,43 @@
|
||||
This extension provides global secrets for use in your pipelines. This extension is a direct port of the global secret file in Drone 0.8. _Please note this project requires Drone server version 1.4 or higher._
|
||||
|
||||
## Secret File
|
||||
|
||||
Secrets are loaded from a yaml configuration file. Example secrets configuration file:
|
||||
|
||||
```text
|
||||
- name: docker_username
|
||||
value: octocat
|
||||
|
||||
- name: docker_password
|
||||
value: correct-horse-battery-staple
|
||||
repos: [ octocat/hello-world, github/* ]
|
||||
events: [ push, tag ]
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
Create a shared secret:
|
||||
|
||||
```console
|
||||
$ openssl rand -hex 16
|
||||
bea26a2221fd8090ea38720fc445eca6
|
||||
```
|
||||
|
||||
Download and run the plugin:
|
||||
|
||||
```console
|
||||
$ docker run -d \
|
||||
--publish=3000:3000 \
|
||||
--env=DRONE_DEBUG=true \
|
||||
--env=DRONE_SECRET=bea26a2221fd8090ea38720fc445eca6 \
|
||||
--env=DRONE_SECRET_FILE=/etc/secrets.yml \
|
||||
--restart=always \
|
||||
--volume=/etc/secrets.yml:/etc/secrets.yml \
|
||||
--name=secrets drone/secret-plugin
|
||||
```
|
||||
|
||||
Update your Drone __runner__ configuration to include the extension address and the shared secret.
|
||||
|
||||
```text
|
||||
DRONE_SECRET_PLUGIN_ENDPOINT=http://1.2.3.4:3000
|
||||
DRONE_SECRET_PLUGIN_SECRET=bea26a2221fd8090ea38720fc445eca6
|
@ -0,0 +1,12 @@
|
||||
module github.com/drone/drone-secret-plugin
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/drone/drone-go v1.0.6
|
||||
github.com/google/go-cmp v0.2.0
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
gopkg.in/yaml.v2 v2.2.7
|
||||
)
|
@ -0,0 +1,48 @@
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e h1:rl2Aq4ZODqTDkeSqQBy+fzpZPamacO1Srp8zq7jf2Sc=
|
||||
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/drone/drone-go v1.0.6 h1:YbMwEwlE3HC4InN0bT21EDvzImct5dGG1I56dSdUhjI=
|
||||
github.com/drone/drone-go v1.0.6/go.mod h1:GxyeGClYohaKNYJv/ZpsmVHtMJ7WhoT+uDaJNcDIrk4=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-jsonnet v0.13.0/go.mod h1:gNwctc8xrpXNs749bjRLO58rjIBVrWz+pgsRoOCh5Vs=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
go.starlark.net v0.0.0-20190820173200-988906f77f65 h1:0766L84ADcyJQKl+NsKSJC8JBEuer/2RxL37StWfsx4=
|
||||
go.starlark.net v0.0.0-20190820173200-988906f77f65/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
@ -0,0 +1,93 @@
|
||||
# Polyform Free Trial License 1.0.0
|
||||
|
||||
<https://polyformproject.org/licenses/free-trial/1.0.0>
|
||||
|
||||
## Acceptance
|
||||
|
||||
In order to get any license under these terms, you must agree
|
||||
to them as both strict obligations and conditions to all
|
||||
your licenses.
|
||||
|
||||
## Copyright License
|
||||
|
||||
The licensor grants you a copyright license for the software
|
||||
to do everything you might do with the software that would
|
||||
otherwise infringe the licensor's copyright in it for any
|
||||
permitted purpose. However, you may only make changes or
|
||||
new works based on the software according to [Changes and New
|
||||
Works License](#changes-and-new-works-license), and you may
|
||||
not distribute copies of the software.
|
||||
|
||||
## Changes and New Works License
|
||||
|
||||
The licensor grants you an additional copyright license to
|
||||
make changes and new works based on the software for any
|
||||
permitted purpose.
|
||||
|
||||
## Patent License
|
||||
|
||||
The licensor grants you a patent license for the software that
|
||||
covers patent claims the licensor can license, or becomes able
|
||||
to license, that you would infringe by using the software.
|
||||
|
||||
## Fair Use
|
||||
|
||||
You may have "fair use" rights for the software under the
|
||||
law. These terms do not limit them.
|
||||
|
||||
## Free Trial
|
||||
|
||||
Use to evaluate whether the software suits a particular
|
||||
application for less than 32 consecutive calendar days, on
|
||||
behalf of you or your company, is use for a permitted purpose.
|
||||
|
||||
## No Other Rights
|
||||
|
||||
These terms do not allow you to sublicense or transfer any of
|
||||
your licenses to anyone else, or prevent the licensor from
|
||||
granting licenses to anyone else. These terms do not imply
|
||||
any other licenses.
|
||||
|
||||
## Patent Defense
|
||||
|
||||
If you make any written claim that the software infringes or
|
||||
contributes to infringement of any patent, your patent license
|
||||
for the software granted under these terms ends immediately. If
|
||||
your company makes such a claim, your patent license ends
|
||||
immediately for work on behalf of your company.
|
||||
|
||||
## Violations
|
||||
|
||||
If you violate any of these terms, or do anything with the
|
||||
software not covered by your licenses, all your licenses
|
||||
end immediately.
|
||||
|
||||
## No Liability
|
||||
|
||||
***As far as the law allows, the software comes as is, without
|
||||
any warranty or condition, and the licensor will not be liable
|
||||
to you for any damages arising out of these terms or the use
|
||||
or nature of the software, under any kind of legal claim.***
|
||||
|
||||
## Definitions
|
||||
|
||||
The **licensor** is the individual or entity offering these
|
||||
terms, and the **software** is the software the licensor makes
|
||||
available under these terms.
|
||||
|
||||
**You** refers to the individual or entity agreeing to these
|
||||
terms.
|
||||
|
||||
**Your company** is any legal entity, sole proprietorship,
|
||||
or other kind of organization that you work for, plus all
|
||||
organizations that have control over, are under the control of,
|
||||
or are under common control with that organization. **Control**
|
||||
means ownership of substantially all the assets of an entity,
|
||||
or the power to direct its management and policies by vote,
|
||||
contract, or otherwise. Control can be direct or indirect.
|
||||
|
||||
**Your licenses** are all the licenses granted to you for the
|
||||
software under these terms.
|
||||
|
||||
**Use** means anything you do with the software requiring one
|
||||
of your licenses.
|
@ -0,0 +1,68 @@
|
||||
// Copyright 2019 the Drone Authors. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform License
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone-go/plugin/secret"
|
||||
"github.com/drone/drone-secret-plugin/plugin"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// spec provides the plugin settings.
|
||||
type spec struct {
|
||||
Bind string `envconfig:"DRONE_BIND"`
|
||||
Debug bool `envconfig:"DRONE_DEBUG"`
|
||||
Secret string `envconfig:"DRONE_SECRET"`
|
||||
File string `envconfig:"DRONE_SECRET_FILE"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
spec := new(spec)
|
||||
err := envconfig.Process("", spec)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if spec.Debug {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
if spec.Secret == "" {
|
||||
logrus.Fatalln("missing secret key")
|
||||
}
|
||||
if spec.Bind == "" {
|
||||
spec.Bind = ":3000"
|
||||
}
|
||||
if spec.File == "" {
|
||||
spec.File = "/etc/secrets.yml"
|
||||
}
|
||||
|
||||
raw, err := ioutil.ReadFile(spec.File)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalln("Cannot read secrets file")
|
||||
}
|
||||
|
||||
var secrets []*plugin.Secret
|
||||
if err := yaml.Unmarshal(raw, &secrets); err != nil {
|
||||
logrus.WithError(err).Fatalln("Cannot unmarshal secrets file")
|
||||
}
|
||||
|
||||
handler := secret.Handler(
|
||||
spec.Secret,
|
||||
plugin.New(secrets),
|
||||
logrus.StandardLogger(),
|
||||
)
|
||||
|
||||
logrus.Infof("server listening on address %s", spec.Bind)
|
||||
|
||||
http.Handle("/", handler)
|
||||
logrus.Fatal(http.ListenAndServe(spec.Bind, nil))
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
// Copyright 2019 the Drone Authors. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform License
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/secret"
|
||||
)
|
||||
|
||||
// New returns a new secret plugin.
|
||||
func New(secrets []*Secret) secret.Plugin {
|
||||
return &plugin{
|
||||
secrets: secrets,
|
||||
}
|
||||
}
|
||||
|
||||
type plugin struct {
|
||||
secrets []*Secret
|
||||
}
|
||||
|
||||
// Find returns the named plugin from the static list of secrets,
|
||||
// if an only if the name, repository, branch and event match.
|
||||
func (p *plugin) Find(ctx context.Context, req *secret.Request) (*drone.Secret, error) {
|
||||
for _, secret := range p.secrets {
|
||||
// if the secret does not match the name, continue
|
||||
if !strings.EqualFold(secret.Name, req.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// if the secret does not match the repository name,
|
||||
// build event, or branch, skip.
|
||||
if !match(req.Build.Event, secret.Events) {
|
||||
continue
|
||||
}
|
||||
if !match(req.Repo.Slug, secret.Repos) {
|
||||
continue
|
||||
}
|
||||
|
||||
return &drone.Secret{
|
||||
Name: secret.Name,
|
||||
Data: secret.Value,
|
||||
Pull: true,
|
||||
Fork: true,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// helper function returns true if string s matches a
|
||||
// string in the index.
|
||||
func match(s string, patterns []string) bool {
|
||||
// if the patterns matching list is empty the
|
||||
// string is considered a match.
|
||||
if len(patterns) == 0 {
|
||||
return true
|
||||
}
|
||||
// if the string matches any pattern in the
|
||||
// list it is considered a match.
|
||||
for _, pattern := range patterns {
|
||||
matched, _ := filepath.Match(pattern, s)
|
||||
if matched {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
// Copyright 2019 the Drone Authors. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform License
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/secret"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
var noContext = context.Background()
|
||||
|
||||
func TestPlugin(t *testing.T) {
|
||||
secrets := []*Secret{
|
||||
{
|
||||
Name: "username",
|
||||
Value: "root",
|
||||
Repos: []string{},
|
||||
Events: []string{},
|
||||
},
|
||||
{
|
||||
Name: "password",
|
||||
Value: "correct-horse-battery-staple",
|
||||
Repos: []string{},
|
||||
Events: []string{},
|
||||
},
|
||||
}
|
||||
req := &secret.Request{
|
||||
Name: "username",
|
||||
Repo: drone.Repo{},
|
||||
Build: drone.Build{},
|
||||
}
|
||||
plugin := New(secrets)
|
||||
got, err := plugin.Find(noContext, req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
want := &drone.Secret{
|
||||
Name: "username",
|
||||
Data: "root",
|
||||
Pull: true,
|
||||
Fork: true,
|
||||
}
|
||||
if diff := cmp.Diff(got, want); diff != "" {
|
||||
t.Errorf("Unexpected secret")
|
||||
t.Logf(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin_Match(t *testing.T) {
|
||||
secrets := []*Secret{
|
||||
{
|
||||
Name: "username",
|
||||
Value: "root",
|
||||
Repos: []string{"octocat/*"},
|
||||
Events: []string{},
|
||||
},
|
||||
}
|
||||
req := &secret.Request{
|
||||
Name: "username",
|
||||
Repo: drone.Repo{Slug: "octocat/hello-world"},
|
||||
Build: drone.Build{Event: "push"},
|
||||
}
|
||||
plugin := New(secrets)
|
||||
got, err := plugin.Find(noContext, req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
want := &drone.Secret{
|
||||
Name: "username",
|
||||
Data: "root",
|
||||
Pull: true,
|
||||
Fork: true,
|
||||
}
|
||||
if diff := cmp.Diff(got, want); diff != "" {
|
||||
t.Errorf("Unexpected secret")
|
||||
t.Logf(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin_NoMatch(t *testing.T) {
|
||||
secrets := []*Secret{
|
||||
{
|
||||
Name: "username",
|
||||
Value: "root",
|
||||
},
|
||||
}
|
||||
req := &secret.Request{
|
||||
Name: "password",
|
||||
Repo: drone.Repo{Slug: "octocat/hello-world"},
|
||||
Build: drone.Build{Event: "push"},
|
||||
}
|
||||
plugin := New(secrets)
|
||||
got, err := plugin.Find(noContext, req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if got != nil {
|
||||
t.Errorf("Expect nil secret due to event mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin_NoMatch_Repo(t *testing.T) {
|
||||
secrets := []*Secret{
|
||||
{
|
||||
Name: "username",
|
||||
Value: "root",
|
||||
Repos: []string{"octocat/*"},
|
||||
Events: []string{},
|
||||
},
|
||||
}
|
||||
req := &secret.Request{
|
||||
Name: "username",
|
||||
Repo: drone.Repo{Slug: "spaceghost/hello-world"},
|
||||
Build: drone.Build{Event: "push"},
|
||||
}
|
||||
plugin := New(secrets)
|
||||
got, err := plugin.Find(noContext, req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if got != nil {
|
||||
t.Errorf("Expect nil secret due to repository mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin_NoMatch_Event(t *testing.T) {
|
||||
secrets := []*Secret{
|
||||
{
|
||||
Name: "username",
|
||||
Value: "root",
|
||||
Repos: []string{"octocat/*"},
|
||||
Events: []string{"pull_request"},
|
||||
},
|
||||
}
|
||||
req := &secret.Request{
|
||||
Name: "username",
|
||||
Repo: drone.Repo{Slug: "octocat/hello-world"},
|
||||
Build: drone.Build{Event: "push"},
|
||||
}
|
||||
plugin := New(secrets)
|
||||
got, err := plugin.Find(noContext, req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if got != nil {
|
||||
t.Errorf("Expect nil secret due to event mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
tests := []struct {
|
||||
match string
|
||||
patterns []string
|
||||
matched bool
|
||||
}{
|
||||
// event matching
|
||||
{"push", []string{"pull_request", "push"}, true},
|
||||
{"tag", []string{"pull_request", "push"}, false},
|
||||
{"tag", []string{}, true},
|
||||
|
||||
// repo matching
|
||||
{"octocat/hello-world", []string{"octocat/hello-world", "octocat/spoon-fork"}, true},
|
||||
{"octocat/hello-world", []string{"octocat/*", "octocat/spoon-fork"}, true},
|
||||
{"octocat/hello-world", []string{}, true},
|
||||
{"octocat/hello-world", []string{"spaceghost/*"}, false},
|
||||
{"octocat/hello-world", []string{"spaceghost/hello-world"}, false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, want := match(test.match, test.patterns), test.matched
|
||||
if got != want {
|
||||
t.Errorf("Want matched %v for string %q and patterns %v",
|
||||
test.matched,
|
||||
test.match,
|
||||
test.patterns,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
// Copyright 2019 the Drone Authors. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform License
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package plugin
|
||||
|
||||
// Secret represents a secret and its matching rules that
|
||||
// determine whether or not a pipeline should be granted
|
||||
// access to the secret value.
|
||||
type Secret struct {
|
||||
Name string
|
||||
Value string
|
||||
Repos []string
|
||||
Events []string
|
||||
}
|
Loading…
Reference in new issue