diff --git a/.gitignore b/.gitignore index 635dff1..b6ea60f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,5 @@ cover/cover socks/proxy socks/image.tar runner/runner -cmd/wcloud/wcloud *.pyc *~ diff --git a/circle.yml b/circle.yml index 3b3c917..eed02d3 100644 --- a/circle.yml +++ b/circle.yml @@ -27,5 +27,4 @@ test: - cd $SRCDIR/cover; make - cd $SRCDIR/socks; make - cd $SRCDIR/runner; make - - cd $SRCDIR/cmd/wcloud; make diff --git a/cmd/wcloud/Makefile b/cmd/wcloud/Makefile deleted file mode 100644 index 86b0df3..0000000 --- a/cmd/wcloud/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -.PHONY: all clean - -all: wcloud - -wcloud: *.go - go get ./$(@D) - go build -o $@ ./$(@D) - -clean: - rm -rf wcloud - go clean ./... diff --git a/cmd/wcloud/cli.go b/cmd/wcloud/cli.go deleted file mode 100644 index ba3c355..0000000 --- a/cmd/wcloud/cli.go +++ /dev/null @@ -1,238 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "os" - "os/user" - "path/filepath" - "strings" - "time" - - "github.com/olekukonko/tablewriter" - "gopkg.in/yaml.v2" -) - -// ArrayFlags allows you to collect repeated flags -type ArrayFlags []string - -func (a *ArrayFlags) String() string { - return strings.Join(*a, ",") -} - -// Set implements flags.Value -func (a *ArrayFlags) Set(value string) error { - *a = append(*a, value) - return nil -} - -func env(key, def string) string { - if val, ok := os.LookupEnv(key); ok { - return val - } - return def -} - -var ( - token = env("SERVICE_TOKEN", "") - baseURL = env("BASE_URL", "https://cloud.weave.works") -) - -func usage() { - fmt.Println(`Usage: - deploy : Deploy image to your configured env - list List recent deployments - config () Get (or set) the configured env - logs Show lots for the given deployment`) -} - -func main() { - if len(os.Args) <= 1 { - usage() - os.Exit(1) - } - - c := NewClient(token, baseURL) - - switch os.Args[1] { - case "deploy": - deploy(c, os.Args[2:]) - case "list": - list(c, os.Args[2:]) - case "config": - config(c, os.Args[2:]) - case "logs": - logs(c, os.Args[2:]) - case "events": - events(c, os.Args[2:]) - case "help": - usage() - default: - usage() - } -} - -func deploy(c Client, args []string) { - var ( - flags = flag.NewFlagSet("", flag.ContinueOnError) - username = flags.String("u", "", "Username to report to deploy service (default with be current user)") - services ArrayFlags - ) - flags.Var(&services, "service", "Service to update (can be repeated)") - if err := flags.Parse(args); err != nil { - usage() - return - } - args = flags.Args() - if len(args) != 1 { - usage() - return - } - parts := strings.SplitN(args[0], ":", 2) - if len(parts) < 2 { - usage() - return - } - if *username == "" { - user, err := user.Current() - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - *username = user.Username - } - deployment := Deployment{ - ImageName: parts[0], - Version: parts[1], - TriggeringUser: *username, - IntendedServices: services, - } - if err := c.Deploy(deployment); err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } -} - -func list(c Client, args []string) { - var ( - flags = flag.NewFlagSet("", flag.ContinueOnError) - since = flags.Duration("since", 7*24*time.Hour, "How far back to fetch results") - ) - if err := flags.Parse(args); err != nil { - usage() - return - } - through := time.Now() - from := through.Add(-*since) - deployments, err := c.GetDeployments(from.Unix(), through.Unix()) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"Created", "ID", "Image", "Version", "State"}) - table.SetBorder(false) - table.SetColumnSeparator(" ") - for _, deployment := range deployments { - table.Append([]string{ - deployment.CreatedAt.Format(time.RFC822), - deployment.ID, - deployment.ImageName, - deployment.Version, - deployment.State, - }) - } - table.Render() -} - -func events(c Client, args []string) { - var ( - flags = flag.NewFlagSet("", flag.ContinueOnError) - since = flags.Duration("since", 7*24*time.Hour, "How far back to fetch results") - ) - if err := flags.Parse(args); err != nil { - usage() - return - } - through := time.Now() - from := through.Add(-*since) - events, err := c.GetEvents(from.Unix(), through.Unix()) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println("events: ", string(events)) -} - -func loadConfig(filename string) (*Config, error) { - extension := filepath.Ext(filename) - var config Config - buf, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - if extension == ".yaml" || extension == ".yml" { - if err := yaml.Unmarshal(buf, &config); err != nil { - return nil, err - } - } else { - if err := json.NewDecoder(bytes.NewReader(buf)).Decode(&config); err != nil { - return nil, err - } - } - return &config, nil -} - -func config(c Client, args []string) { - if len(args) > 1 { - usage() - return - } - - if len(args) == 1 { - config, err := loadConfig(args[0]) - if err != nil { - fmt.Println("Error reading config:", err) - os.Exit(1) - } - - if err := c.SetConfig(config); err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - } else { - config, err := c.GetConfig() - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - buf, err := yaml.Marshal(config) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println(string(buf)) - } -} - -func logs(c Client, args []string) { - if len(args) != 1 { - usage() - return - } - - output, err := c.GetLogs(args[0]) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println(string(output)) -} diff --git a/cmd/wcloud/client.go b/cmd/wcloud/client.go deleted file mode 100644 index 02cbbaa..0000000 --- a/cmd/wcloud/client.go +++ /dev/null @@ -1,150 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" -) - -// Client for the deployment service -type Client struct { - token string - baseURL string -} - -// NewClient makes a new Client -func NewClient(token, baseURL string) Client { - return Client{ - token: token, - baseURL: baseURL, - } -} - -func (c Client) newRequest(method, path string, body io.Reader) (*http.Request, error) { - req, err := http.NewRequest(method, c.baseURL+path, body) - if err != nil { - return nil, err - } - req.Header.Add("Authorization", fmt.Sprintf("Scope-Probe token=%s", c.token)) - return req, nil -} - -// Deploy notifies the deployment service about a new deployment -func (c Client) Deploy(deployment Deployment) error { - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(deployment); err != nil { - return err - } - req, err := c.newRequest("POST", "/api/deploy/deploy", &buf) - if err != nil { - return err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - if res.StatusCode != 204 { - return fmt.Errorf("error making request: %s", res.Status) - } - return nil -} - -// GetDeployments returns a list of deployments -func (c Client) GetDeployments(from, through int64) ([]Deployment, error) { - req, err := c.newRequest("GET", fmt.Sprintf("/api/deploy/deploy?from=%d&through=%d", from, through), nil) - if err != nil { - return nil, err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode != 200 { - return nil, fmt.Errorf("error making request: %s", res.Status) - } - var response struct { - Deployments []Deployment `json:"deployments"` - } - if err := json.NewDecoder(res.Body).Decode(&response); err != nil { - return nil, err - } - return response.Deployments, nil -} - -// GetEvents returns the raw events. -func (c Client) GetEvents(from, through int64) ([]byte, error) { - req, err := c.newRequest("GET", fmt.Sprintf("/api/deploy/event?from=%d&through=%d", from, through), nil) - if err != nil { - return nil, err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode != 200 { - return nil, fmt.Errorf("error making request: %s", res.Status) - } - return ioutil.ReadAll(res.Body) -} - -// GetConfig returns the current Config -func (c Client) GetConfig() (*Config, error) { - req, err := c.newRequest("GET", "/api/config/deploy", nil) - if err != nil { - return nil, err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode == 404 { - return nil, fmt.Errorf("no configuration uploaded yet") - } - if res.StatusCode != 200 { - return nil, fmt.Errorf("error making request: %s", res.Status) - } - var config Config - if err := json.NewDecoder(res.Body).Decode(&config); err != nil { - return nil, err - } - return &config, nil -} - -// SetConfig sets the current Config -func (c Client) SetConfig(config *Config) error { - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(config); err != nil { - return err - } - req, err := c.newRequest("POST", "/api/config/deploy", &buf) - if err != nil { - return err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - if res.StatusCode != 204 { - return fmt.Errorf("error making request: %s", res.Status) - } - return nil -} - -// GetLogs returns the logs for a given deployment. -func (c Client) GetLogs(deployID string) ([]byte, error) { - req, err := c.newRequest("GET", fmt.Sprintf("/api/deploy/deploy/%s/log", deployID), nil) - if err != nil { - return nil, err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode != 200 { - return nil, fmt.Errorf("error making request: %s", res.Status) - } - return ioutil.ReadAll(res.Body) -} diff --git a/cmd/wcloud/types.go b/cmd/wcloud/types.go deleted file mode 100644 index a068163..0000000 --- a/cmd/wcloud/types.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "time" -) - -// Deployment describes a deployment -type Deployment struct { - ID string `json:"id"` - CreatedAt time.Time `json:"created_at"` - ImageName string `json:"image_name"` - Version string `json:"version"` - Priority int `json:"priority"` - State string `json:"status"` - - TriggeringUser string `json:"triggering_user"` - IntendedServices []string `json:"intended_services"` -} - -// Config for the deployment system for a user. -type Config struct { - RepoURL string `json:"repo_url" yaml:"repo_url"` - RepoBranch string `json:"repo_branch" yaml:"repo_branch"` - RepoPath string `json:"repo_path" yaml:"repo_path"` - RepoKey string `json:"repo_key" yaml:"repo_key"` - KubeconfigPath string `json:"kubeconfig_path" yaml:"kubeconfig_path"` - AutoApply bool `json:"auto_apply" yaml:"auto_apply"` - - Notifications []NotificationConfig `json:"notifications" yaml:"notifications"` - - // Globs of files not to change, relative to the route of the repo - ConfigFileBlackList []string `json:"config_file_black_list" yaml:"config_file_black_list"` - - CommitMessageTemplate string `json:"commit_message_template" yaml:"commit_message_template"` // See https://golang.org/pkg/text/template/ -} - -// NotificationConfig describes how to send notifications -type NotificationConfig struct { - SlackWebhookURL string `json:"slack_webhook_url" yaml:"slack_webhook_url"` - SlackUsername string `json:"slack_username" yaml:"slack_username"` - MessageTemplate string `json:"message_template" yaml:"message_template"` - ApplyMessageTemplate string `json:"apply_message_template" yaml:"apply_message_template"` -}