From 161eccf6f1567f6454cdb52f43d12a558eca67d2 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Mon, 6 Aug 2018 16:29:03 -0700 Subject: [PATCH] add cron CLI commands --- Gopkg.lock | 4 +- Gopkg.toml | 2 +- drone/cron/cron.go | 15 ++++ drone/cron/cron_add.go | 44 ++++++++++++ drone/cron/cron_info.go | 48 +++++++++++++ drone/cron/cron_list.go | 55 +++++++++++++++ drone/cron/cron_rm.go | 28 ++++++++ drone/encrypt/encrypt.go | 66 ++++++++++++++++++ drone/main.go | 4 ++ .../github.com/drone/drone-go/drone/client.go | 69 +++++++++++++++++++ .../github.com/drone/drone-go/drone/const.go | 6 ++ .../drone/drone-go/drone/interface.go | 15 ++++ .../github.com/drone/drone-go/drone/types.go | 13 ++++ 13 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 drone/cron/cron.go create mode 100644 drone/cron/cron_add.go create mode 100644 drone/cron/cron_info.go create mode 100644 drone/cron/cron_list.go create mode 100644 drone/cron/cron_rm.go create mode 100644 drone/encrypt/encrypt.go diff --git a/Gopkg.lock b/Gopkg.lock index 766a48c..5abfad9 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -85,7 +85,7 @@ [[projects]] name = "github.com/drone/drone-go" packages = ["drone"] - revision = "7f20e6c113d3ffa2af80401c4eba7d510c8fd875" + revision = "dd0a126edb93bbff0df4d0c5deaba3aa70f0f931" [[projects]] branch = "master" @@ -245,6 +245,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "3c2492a2f392e0e4d42f2247aca5631e020aed1e2dea238bb56e27739866927a" + inputs-digest = "209ae0d5ae4c09846a52ff66c6928530c3ce74044bebbc11f0dadceb574c51f6" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a8d9f67..c135980 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -7,7 +7,7 @@ [[constraint]] name = "github.com/drone/drone-go" - revision = "7f20e6c113d3ffa2af80401c4eba7d510c8fd875" + revision = "dd0a126edb93bbff0df4d0c5deaba3aa70f0f931" [[constraint]] branch = "master" diff --git a/drone/cron/cron.go b/drone/cron/cron.go new file mode 100644 index 0000000..7f77c6c --- /dev/null +++ b/drone/cron/cron.go @@ -0,0 +1,15 @@ +package cron + +import "github.com/urfave/cli" + +// Command exports the registry command set. +var Command = cli.Command{ + Name: "cron", + Usage: "manage cron jobs", + Subcommands: []cli.Command{ + cronCreateCmd, + cronDeleteCmd, + cronInfoCmd, + cronListCmd, + }, +} diff --git a/drone/cron/cron_add.go b/drone/cron/cron_add.go new file mode 100644 index 0000000..7780a6e --- /dev/null +++ b/drone/cron/cron_add.go @@ -0,0 +1,44 @@ +package cron + +import ( + "github.com/drone/drone-cli/drone/internal" + "github.com/drone/drone-go/drone" + + "github.com/urfave/cli" +) + +var cronCreateCmd = cli.Command{ + Name: "add", + Usage: "adds a cronjob", + ArgsUsage: "[repo/name]", + Action: cronCreate, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "branch", + Usage: "branch name", + Value: "master", + }, + }, +} + +func cronCreate(c *cli.Context) error { + slug := c.Args().First() + owner, name, err := internal.ParseRepo(slug) + if err != nil { + return err + } + client, err := internal.NewClient(c) + if err != nil { + return err + } + cron := &drone.Cron{ + Name: c.Args().Get(1), + Expr: c.Args().Get(2), + Branch: c.String("branch"), + } + _, err = client.CronCreate(owner, name, cron) + if err != nil { + return err + } + return nil +} diff --git a/drone/cron/cron_info.go b/drone/cron/cron_info.go new file mode 100644 index 0000000..2808313 --- /dev/null +++ b/drone/cron/cron_info.go @@ -0,0 +1,48 @@ +package cron + +import ( + "html/template" + "os" + + "github.com/drone/drone-cli/drone/internal" + + "github.com/urfave/cli" +) + +var cronInfoCmd = cli.Command{ + Name: "info", + Usage: "display cron info", + ArgsUsage: "[repo/name]", + Action: cronInfo, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "format", + Usage: "format output", + Value: tmplCronList, + Hidden: true, + }, + }, +} + +func cronInfo(c *cli.Context) error { + slug := c.Args().First() + owner, name, err := internal.ParseRepo(slug) + if err != nil { + return err + } + client, err := internal.NewClient(c) + if err != nil { + return err + } + cronjob := c.Args().Get(1) + cron, err := client.Cron(owner, name, cronjob) + if err != nil { + return err + } + format := c.String("format") + tmpl, err := template.New("_").Parse(format) + if err != nil { + return err + } + return tmpl.Execute(os.Stdout, cron) +} diff --git a/drone/cron/cron_list.go b/drone/cron/cron_list.go new file mode 100644 index 0000000..56bb5bc --- /dev/null +++ b/drone/cron/cron_list.go @@ -0,0 +1,55 @@ +package cron + +import ( + "html/template" + "os" + + "github.com/urfave/cli" + + "github.com/drone/drone-cli/drone/internal" +) + +var cronListCmd = cli.Command{ + Name: "ls", + Usage: "list cron jobs", + ArgsUsage: "[repo/name]", + Action: cronList, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "format", + Usage: "format output", + Value: tmplCronList, + Hidden: true, + }, + }, +} + +func cronList(c *cli.Context) error { + slug := c.Args().First() + owner, name, err := internal.ParseRepo(slug) + if err != nil { + return err + } + client, err := internal.NewClient(c) + if err != nil { + return err + } + list, err := client.CronList(owner, name) + if err != nil { + return err + } + format := c.String("format") + "\n" + tmpl, err := template.New("_").Parse(format) + if err != nil { + return err + } + for _, cron := range list { + tmpl.Execute(os.Stdout, cron) + } + return nil +} + +// template for build list information +var tmplCronList = "\x1b[33m{{ .Name }} \x1b[0m" + ` +Expr: {{ .Expr }} +` diff --git a/drone/cron/cron_rm.go b/drone/cron/cron_rm.go new file mode 100644 index 0000000..f2aa3d4 --- /dev/null +++ b/drone/cron/cron_rm.go @@ -0,0 +1,28 @@ +package cron + +import ( + "github.com/drone/drone-cli/drone/internal" + + "github.com/urfave/cli" +) + +var cronDeleteCmd = cli.Command{ + Name: "rm", + Usage: "display cron rm", + ArgsUsage: "[repo/name]", + Action: cronDelete, +} + +func cronDelete(c *cli.Context) error { + slug := c.Args().First() + owner, name, err := internal.ParseRepo(slug) + if err != nil { + return err + } + client, err := internal.NewClient(c) + if err != nil { + return err + } + cronjob := c.Args().Get(1) + return client.CronDelete(owner, name, cronjob) +} diff --git a/drone/encrypt/encrypt.go b/drone/encrypt/encrypt.go new file mode 100644 index 0000000..e969533 --- /dev/null +++ b/drone/encrypt/encrypt.go @@ -0,0 +1,66 @@ +package encrypt + +import ( + "fmt" + "io/ioutil" + "strings" + + "github.com/drone/drone-cli/drone/internal" + + "github.com/urfave/cli" +) + +// Command exports the deploy command. +var Command = cli.Command{ + Name: "encrypt", + Usage: "encrypt a string", + ArgsUsage: " ", + Action: encrypt, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "aesgcm", + Usage: "aesgcm encryption", + }, + cli.BoolFlag{ + Name: "secretbox", + Usage: "secretbox encryption", + }, + }, +} + +func encrypt(c *cli.Context) error { + repo := c.Args().First() + owner, name, err := internal.ParseRepo(repo) + if err != nil { + return err + } + + client, err := internal.NewClient(c) + if err != nil { + return err + } + + var algorithm string + switch { + case c.Bool("asesgcm"): + algorithm = "asesgcm" + default: + algorithm = "secretbox" + } + + plaintext := c.Args().Get(1) + if strings.HasPrefix(plaintext, "@") { + data, err := ioutil.ReadFile(plaintext) + if err != nil { + return err + } + plaintext = string(data) + } + + ciphertext, err := client.Encrypt(owner, name, plaintext, algorithm) + if err != nil { + return err + } + fmt.Println(ciphertext) + return nil +} diff --git a/drone/main.go b/drone/main.go index 5d27d73..2449a67 100644 --- a/drone/main.go +++ b/drone/main.go @@ -6,7 +6,9 @@ import ( "github.com/drone/drone-cli/drone/autoscale" "github.com/drone/drone-cli/drone/build" + "github.com/drone/drone-cli/drone/cron" "github.com/drone/drone-cli/drone/deploy" + "github.com/drone/drone-cli/drone/encrypt" "github.com/drone/drone-cli/drone/exec" "github.com/drone/drone-cli/drone/info" "github.com/drone/drone-cli/drone/jsonnet" @@ -68,8 +70,10 @@ func main() { } app.Commands = []cli.Command{ build.Command, + cron.Command, log.Command, deploy.Command, + encrypt.Command, exec.Command, info.Command, registry.Command, diff --git a/vendor/github.com/drone/drone-go/drone/client.go b/vendor/github.com/drone/drone-go/drone/client.go index bcc527b..5380544 100644 --- a/vendor/github.com/drone/drone-go/drone/client.go +++ b/vendor/github.com/drone/drone-go/drone/client.go @@ -32,6 +32,9 @@ const ( pathRepoSecret = "%s/api/repos/%s/%s/secrets/%s" pathRepoRegistries = "%s/api/repos/%s/%s/registry" pathRepoRegistry = "%s/api/repos/%s/%s/registry/%s" + pathEncrypt = "%s/api/repos/%s/%s/encrypt" + pathCrons = "%s/api/repos/%s/%s/cron" + pathCron = "%s/api/repos/%s/%s/cron/%s" pathUsers = "%s/api/users" pathUser = "%s/api/users/%s" pathBuildQueue = "%s/api/builds" @@ -406,6 +409,72 @@ func (c *client) SecretDelete(owner, name, secret string) error { return c.delete(uri) } +// +// encryption +// + +type ( + encryptRequest struct { + Algorithm string `json:"algorithm"` + Plaintext string `json:"plaintext"` + } + + encryptResponse struct { + Algorithm string `json:"algorithm"` + Ciphertext string `json:"ciphertext"` + } +) + +// Encrypt returns an encrypted secret +func (c *client) Encrypt(owner, name, plaintext, algorithm string) (string, error) { + in := &encryptRequest{ + Algorithm: algorithm, + Plaintext: plaintext, + } + out := &encryptResponse{} + uri := fmt.Sprintf(pathEncrypt, c.addr, owner, name) + err := c.post(uri, in, out) + return out.Ciphertext, err +} + +// +// cron jobs +// + +// Cron returns a cronjob by name. +func (c *client) Cron(owner, name, cron string) (*Cron, error) { + out := new(Cron) + uri := fmt.Sprintf(pathCron, c.addr, owner, name, cron) + err := c.get(uri, out) + return out, err +} + +// CronList returns a list of all repository cronjobs. +func (c *client) CronList(owner string, name string) ([]*Cron, error) { + var out []*Cron + uri := fmt.Sprintf(pathCrons, c.addr, owner, name) + err := c.get(uri, &out) + return out, err +} + +// CronCreate creates a cronjob. +func (c *client) CronCreate(owner, name string, in *Cron) (*Cron, error) { + out := new(Cron) + uri := fmt.Sprintf(pathCrons, c.addr, owner, name) + err := c.post(uri, in, out) + return out, err +} + +// CronDelete deletes a cronjob. +func (c *client) CronDelete(owner, name, cron string) error { + uri := fmt.Sprintf(pathCron, c.addr, owner, name, cron) + return c.delete(uri) +} + +// +// autoscaler +// + // Server returns the named servers details. func (c *client) Server(name string) (*Server, error) { out := new(Server) diff --git a/vendor/github.com/drone/drone-go/drone/const.go b/vendor/github.com/drone/drone-go/drone/const.go index f61b612..d830f85 100644 --- a/vendor/github.com/drone/drone-go/drone/const.go +++ b/vendor/github.com/drone/drone-go/drone/const.go @@ -19,3 +19,9 @@ const ( StatusKilled = "killed" StatusError = "error" ) + +// Encryption algorithms +const ( + EncryptAesgcm = "aesgcm" + EncryptSecretbox = "secretbox" +) diff --git a/vendor/github.com/drone/drone-go/drone/interface.go b/vendor/github.com/drone/drone-go/drone/interface.go index 0b24d7f..20b55ec 100644 --- a/vendor/github.com/drone/drone-go/drone/interface.go +++ b/vendor/github.com/drone/drone-go/drone/interface.go @@ -123,6 +123,21 @@ type Client interface { // SecretDelete deletes a secret. SecretDelete(owner, name, secret string) error + // Encrypt returns an encrypted secret + Encrypt(owner, name, plaintext, algorithm string) (string, error) + + // Cron returns a cronjob by name. + Cron(owner, name, cron string) (*Cron, error) + + // CronList returns a list of all repository cronjobs. + CronList(owner string, name string) ([]*Cron, error) + + // CronCreate creates a cronjob. + CronCreate(owner, name string, in *Cron) (*Cron, error) + + // CronDelete deletes a cronjob. + CronDelete(owner, name, cron string) error + // Server returns the named servers details. Server(name string) (*Server, error) diff --git a/vendor/github.com/drone/drone-go/drone/types.go b/vendor/github.com/drone/drone-go/drone/types.go index b805000..f63b2ae 100644 --- a/vendor/github.com/drone/drone-go/drone/types.go +++ b/vendor/github.com/drone/drone-go/drone/types.go @@ -163,6 +163,19 @@ type ( Stopped int64 `json:"stopped"` } + // Cron represents a cron job. + Cron struct { + ID int64 `json:"id"` + RepoID int64 `json:"repo_id"` + Name string `json:"name"` + Expr string `json:"expr"` + Next int64 `json:"next"` + Prev int64 `json:"prev"` + Branch string `json:"branch"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + } + // Version provides system version details. Version struct { Source string `json:"source,omitempty"`