mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-04 10:41:14 +00:00
Add Weave Cloud client
This commit is contained in:
178
cmd/wcloud/cli.go
Normal file
178
cmd/wcloud/cli.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
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 <image>:<version> Deploy image to your configured env
|
||||
list List recent deployments
|
||||
config (<filename>) Get (or set) the configured env
|
||||
logs <deploy> 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 "help":
|
||||
usage()
|
||||
default:
|
||||
usage()
|
||||
}
|
||||
}
|
||||
|
||||
func deploy(c Client, args []string) {
|
||||
if len(args) != 1 {
|
||||
usage()
|
||||
return
|
||||
}
|
||||
parts := strings.SplitN(args[0], ":", 2)
|
||||
if len(parts) < 2 {
|
||||
usage()
|
||||
return
|
||||
}
|
||||
deployment := Deployment{
|
||||
ImageName: parts[0],
|
||||
Version: parts[1],
|
||||
}
|
||||
if err := c.Deploy(deployment); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func list(c Client, args []string) {
|
||||
flags := flag.NewFlagSet("list", flag.ContinueOnError)
|
||||
page := flags.Int("page", 0, "Zero based index of page to list.")
|
||||
pagesize := flags.Int("page-size", 10, "Number of results per page")
|
||||
if err := flags.Parse(args); err != nil {
|
||||
usage()
|
||||
return
|
||||
}
|
||||
deployments, err := c.GetDeployments(*page, *pagesize)
|
||||
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 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))
|
||||
}
|
||||
131
cmd/wcloud/client.go
Normal file
131
cmd/wcloud/client.go
Normal file
@@ -0,0 +1,131 @@
|
||||
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", &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(page, pagesize int) ([]Deployment, error) {
|
||||
req, err := c.newRequest("GET", fmt.Sprintf("/api/deploy?page=%d&pagesize=%d", page, pagesize), 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
|
||||
}
|
||||
|
||||
// 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 != 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/%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)
|
||||
}
|
||||
24
cmd/wcloud/types.go
Normal file
24
cmd/wcloud/types.go
Normal file
@@ -0,0 +1,24 @@
|
||||
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"`
|
||||
LogKey string `json:"-"`
|
||||
}
|
||||
|
||||
// Config for the deployment system for a user.
|
||||
type Config struct {
|
||||
RepoURL string `json:"repo_url" yaml:"repo_url"`
|
||||
RepoPath string `json:"repo_path" yaml:"repo_path"`
|
||||
RepoKey string `json:"repo_key" yaml:"repo_key"`
|
||||
KubeconfigPath string `json:"kubeconfig_path" yaml:"kubeconfig_path"`
|
||||
}
|
||||
Reference in New Issue
Block a user