Merge pull request #1693 from tboerger/feature/secret-list

Integrated initial command to list secrets
This commit is contained in:
Brad Rydzewski 2016-06-27 15:24:38 -07:00 committed by GitHub
commit 2d7c7bd860
8 changed files with 144 additions and 6 deletions

View file

@ -49,6 +49,9 @@ type Client interface {
// Sign returns a cryptographic signature for the input string.
Sign(string, string, []byte) ([]byte, error)
// SecretList returns a list of all repository secrets.
SecretList(string, string) ([]*model.Secret, error)
// SecretPost create or updates a repository secret.
SecretPost(string, string, *model.Secret) error

View file

@ -247,6 +247,14 @@ func (c *client) Deploy(owner, name string, num int, env string) (*model.Build,
return out, err
}
// SecretList returns a list of a repository secrets.
func (c *client) SecretList(owner, name string) ([]*model.Secret, error) {
var out []*model.Secret
uri := fmt.Sprintf(pathSecrets, c.base, owner, name)
err := c.get(uri, &out)
return out, err
}
// 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)

View file

@ -8,5 +8,6 @@ var secretCmd = cli.Command{
Subcommands: []cli.Command{
secretAddCmd,
secretRemoveCmd,
secretListCmd,
},
}

View file

@ -1 +1,87 @@
package main
import (
"log"
"os"
"strings"
"text/template"
"github.com/codegangsta/cli"
)
var secretListCmd = cli.Command{
Name: "ls",
Usage: "list all secrets",
Action: func(c *cli.Context) {
if err := secretList(c); err != nil {
log.Fatalln(err)
}
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "format",
Usage: "format output",
Value: tmplSecretList,
},
cli.StringFlag{
Name: "image",
Usage: "filter by image",
},
cli.StringFlag{
Name: "event",
Usage: "filter by event",
},
},
}
func secretList(c *cli.Context) error {
owner, name, err := parseRepo(c.Args().First())
if err != nil {
return err
}
client, err := newClient(c)
if err != nil {
return err
}
secrets, err := client.SecretList(owner, name)
if err != nil || len(secrets) == 0 {
return err
}
tmpl, err := template.New("_").Funcs(secretFuncMap).Parse(c.String("format") + "\n")
if err != nil {
return err
}
for _, secret := range secrets {
if c.String("image") != "" && !stringInSlice(c.String("image"), secret.Images) {
continue
}
if c.String("event") != "" && !stringInSlice(c.String("event"), secret.Events) {
continue
}
tmpl.Execute(os.Stdout, secret)
}
return nil
}
// template for secret list items
var tmplSecretList = "\x1b[33m{{ .Name }} \x1b[0m" + `
Images: {{ list .Images }}
Events: {{ list .Events }}
`
var secretFuncMap = template.FuncMap{
"list": func(s []string) string {
return strings.Join(s, ", ")
},
}

View file

@ -51,3 +51,13 @@ func readInput(in string) ([]byte, error) {
}
return ioutil.ReadFile(in)
}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}

View file

@ -55,3 +55,12 @@ func (s *Secret) MatchEvent(event string) bool {
func (s *Secret) Validate() error {
return nil
}
func (s *Secret) Clone() *Secret {
return &Secret{
ID: s.ID,
Name: s.Name,
Images: s.Images,
Events: s.Events,
}
}

View file

@ -97,6 +97,7 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
repo.GET("/logs/:number/:job", server.GetBuildLogs)
repo.POST("/sign", session.MustPush, server.Sign)
repo.GET("/secrets", session.MustPush, server.GetSecrets)
repo.POST("/secrets", session.MustPush, server.PostSecret)
repo.DELETE("/secrets/:secret", session.MustPush, server.DeleteSecret)

View file

@ -1,6 +1,8 @@
package server
import (
"net/http"
"github.com/drone/drone/model"
"github.com/drone/drone/router/middleware/session"
"github.com/drone/drone/store"
@ -8,13 +10,31 @@ import (
"github.com/gin-gonic/gin"
)
func GetSecrets(c *gin.Context) {
repo := session.Repo(c)
secrets, err := store.GetSecretList(c, repo)
if err != nil {
c.AbortWithStatus(http.StatusInternalServerError)
return
}
var list []*model.Secret
for _, s := range secrets {
list = append(list, s.Clone())
}
c.JSON(http.StatusOK, list)
}
func PostSecret(c *gin.Context) {
repo := session.Repo(c)
in := &model.Secret{}
err := c.Bind(in)
if err != nil {
c.String(400, "Invalid JSON input. %s", err.Error())
c.String(http.StatusBadRequest, "Invalid JSON input. %s", err.Error())
return
}
in.ID = 0
@ -22,11 +42,11 @@ func PostSecret(c *gin.Context) {
err = store.SetSecret(c, in)
if err != nil {
c.String(500, "Unable to persist secret. %s", err.Error())
c.String(http.StatusInternalServerError, "Unable to persist secret. %s", err.Error())
return
}
c.String(200, "")
c.String(http.StatusOK, "")
}
func DeleteSecret(c *gin.Context) {
@ -35,14 +55,14 @@ func DeleteSecret(c *gin.Context) {
secret, err := store.GetSecret(c, repo, name)
if err != nil {
c.String(404, "Cannot find secret %s.", name)
c.String(http.StatusNotFound, "Cannot find secret %s.", name)
return
}
err = store.DeleteSecret(c, secret)
if err != nil {
c.String(500, "Unable to delete secret. %s", err.Error())
c.String(http.StatusInternalServerError, "Unable to delete secret. %s", err.Error())
return
}
c.String(200, "")
c.String(http.StatusOK, "")
}