Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var APICommand = cli.Command{ Name: "api", Usage: "Call Barcelona API", ArgsUsage: "METHOD PATH [BODY]", Action: func(c *cli.Context) error { method := strings.ToUpper(c.Args().Get(0)) path := c.Args().Get(1) body := bytes.NewBufferString(c.Args().Get(2)) oper := operations.NewApiOperation(method, path, body, api.DefaultClient) return operations.Execute(oper) }, }
View Source
var AppCommand = cli.Command{ Name: "app", Usage: "Manage heritages", Subcommands: []cli.Command{ { Name: "delete", Usage: "Delete a heritage", ArgsUsage: "HERITAGE_NAME", Flags: []cli.Flag{ cli.BoolFlag{ Name: "no-confirmation", }, }, Action: func(c *cli.Context) error { name := c.Args().Get(0) oper := operations.NewAppOperation(name, operations.Delete, c.Bool("no-confirmation"), api.DefaultClient, utils.NewStdinInputReader()) return operations.Execute(oper) }, }, { Name: "show", Usage: "Show a heritage", ArgsUsage: "HERITAGE_NAME", Action: func(c *cli.Context) error { name := c.Args().Get(0) oper := operations.NewAppOperation(name, operations.Show, false, api.DefaultClient, utils.NewStdinInputReader()) return operations.Execute(oper) }, }, }, }
View Source
var CreateCommand = cli.Command{ Name: "create", Usage: "Create a new Barcelona heritage", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, cli.StringFlag{ Name: "tag, t", Value: "latest", Usage: "District name", }, }, Action: func(c *cli.Context) error { h, err := LoadEnvironment(c.String("environment")) if err != nil { return cli.NewExitError(err.Error(), 1) } h.FillinDefaults() h.ImageTag = c.String("tag") resp, err := api.DefaultClient.CreateHeritage(c.String("district"), h) if err != nil { return cli.NewExitError(err.Error(), 1) } resp.Print() return nil }, }
View Source
var DeployCommand = cli.Command{ Name: "deploy", Usage: "Deploy a Barcelona heritage", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "tag, t", Usage: "Tag of docker image", }, cli.StringFlag{ Name: "heritage-token", Usage: "Heritage token", }, cli.BoolFlag{ Name: "quiet, q", Usage: "Do not print output if successful", }, }, Action: func(c *cli.Context) error { env := c.String("environment") tag := c.String("tag") token := c.String("heritage-token") quiet := c.Bool("quiet") var heritage *api.Heritage var err error if len(token) > 0 { heritage, err = doDeployWithHeritageToken(env, tag, token) } else { heritage, err = doDeploy(env, tag) } if err != nil { return cli.NewExitError(err.Error(), 1) } if !quiet { heritage.Print() } return nil }, }
View Source
var DistrictCommand = cli.Command{ Name: "district", Usage: "District operations", Subcommands: []cli.Command{ { Name: "create", Usage: "Create a new district", ArgsUsage: "DISTRICT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "region", Value: "us-east-1", Usage: "AWS region", }, cli.StringFlag{ Name: "nat-type", Value: "instance", Usage: "NAT type", }, cli.StringFlag{ Name: "cluster-instance-type", Value: "t2.small", Usage: "Cluster Instance Type", }, }, Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } size := 1 request := api.DistrictRequest{ Name: districtName, Region: c.String("region"), NatType: c.String("nat-type"), ClusterSize: &size, ClusterInstanceType: c.String("cluster-instance-type"), ClusterBackend: "autoscaling", } request.AwsAccessKeyId = utils.Ask("AWS Access Key ID", true, false, utils.NewStdinInputReader()) request.AwsSecretAccessKey = utils.Ask("AWS Secret Access Key", true, true, utils.NewStdinInputReader()) district, err := api.DefaultClient.CreateDistrict(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } printDistrict(district) return nil }, }, { Name: "list", Usage: "List Districts", Action: func(c *cli.Context) error { districts, err := api.DefaultClient.ListDistricts() if err != nil { return cli.NewExitError(err.Error(), 1) } printDistricts(districts) return nil }, }, { Name: "show", Usage: "Show District Information", ArgsUsage: "DISTRICT_NAME", Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } district, err := api.DefaultClient.ShowDistrict(districtName) if err != nil { return cli.NewExitError(err.Error(), 1) } printDistrict(district) return nil }, }, { Name: "update", Usage: "Update District Information", ArgsUsage: "DISTRICT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "nat-type", Usage: "NAT type", }, cli.StringFlag{ Name: "cluster-instance-type", Usage: "Cluster Instance Type", }, cli.IntFlag{ Name: "cluster-size", Value: -1, Usage: "Cluster Instance Type", }, cli.BoolFlag{ Name: "apply", Usage: "Apply immediately", }, }, Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } request := api.DistrictRequest{ Name: districtName, NatType: c.String("nat-type"), ClusterInstanceType: c.String("cluster-instance-type"), } if size := c.Int("cluster-size"); size >= 0 { request.ClusterSize = &size } district, err := api.DefaultClient.UpdateDistrict(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } printDistrict(district) err = applyOrNotice(districtName, c.Bool("apply")) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "apply", Usage: "apply district stack", ArgsUsage: "DISTRICT_NAME", Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } err := applyOrNotice(districtName, true) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "delete", Usage: "Delete a district", ArgsUsage: "DISTRICT_NAME", Flags: []cli.Flag{ cli.BoolFlag{ Name: "no-confirmation", }, }, Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } fmt.Printf("You are attempting to delete %s\n", districtName) if !c.Bool("no-confirmation") && !utils.AreYouSure("This operation cannot be undone. Are you sure?", utils.NewStdinInputReader()) { return nil } err := api.DefaultClient.DeleteDistrict(districtName) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "put-plugin", Usage: "Add or Update plugin configuration", ArgsUsage: "DISTRICT_NAME PLUGIN_NAME", Flags: []cli.Flag{ cli.StringSliceFlag{ Name: "attribute, a", Usage: "ATTR_NAME=VALUE", }, cli.BoolFlag{ Name: "apply", Usage: "Apply immediately", }, }, Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } pluginName := c.Args().Get(1) if len(districtName) == 0 { return cli.NewExitError("plugin name is required", 1) } req := api.Plugin{ Name: pluginName, } req.Attributes = make(map[string]string) attrs := c.StringSlice("attribute") for _, s := range attrs { ss := strings.SplitN(s, "=", 2) req.Attributes[ss[0]] = ss[1] } plugin, err := api.DefaultClient.PutPlugin(districtName, &req) if err != nil { return cli.NewExitError(err.Error(), 1) } printPlugin(plugin) err = applyOrNotice(districtName, c.Bool("apply")) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "delete-plugin", Usage: "Delete a plugin", ArgsUsage: "DISTRICT_NAME PLUGIN_NAME", Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } pluginName := c.Args().Get(1) if len(districtName) == 0 { return cli.NewExitError("plugin name is required", 1) } err := api.DefaultClient.DeletePlugin(districtName, pluginName) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "put-dockercfg", Usage: "Add or Replace dockercfg", ArgsUsage: "DISTRICT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "filename, f", Usage: "FILENAME", }, cli.StringFlag{ Name: "config, c", Usage: "JSON", }, cli.BoolFlag{ Name: "apply", Usage: "Apply immediately", }, }, Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } filename := c.String("filename") config := c.String("config") if len(filename) > 0 && len(config) > 0 { return cli.NewExitError("filename and config are exclusive", 1) } var jsonBytes []byte var err error if len(filename) > 0 { jsonBytes, err = ioutil.ReadFile(filename) if err != nil { return cli.NewExitError(err.Error(), 1) } } else if len(config) > 0 { jsonBytes = []byte(config) } else { return cli.NewExitError("Specify dockercfg", 1) } var dockercfg interface{} err = json.Unmarshal(jsonBytes, &dockercfg) if err != nil { return cli.NewExitError(err.Error(), 1) } params := make(map[string]interface{}) params["dockercfg"] = dockercfg paramsB, err := json.Marshal(params) if err != nil { return cli.NewExitError(err.Error(), 1) } _, err = api.DefaultClient.Patch("/districts/"+districtName, bytes.NewBuffer(paramsB)) if err != nil { return cli.NewExitError(err.Error(), 1) } err = applyOrNotice(districtName, c.Bool("apply")) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, }, }
View Source
var EndpointCommand = cli.Command{ Name: "endpoint", Usage: "Endpoint operations", Subcommands: []cli.Command{ { Name: "create", Usage: "Create a new endpoint", ArgsUsage: "ENDPOINT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "AWS region", }, cli.BoolFlag{ Name: "public", Usage: "Public facing endpoint", }, cli.StringFlag{ Name: "certificate-arn", Usage: "ACM Certificate ARN", }, cli.StringFlag{ Name: "ssl-policy", Usage: "HTTPS SSL Policy", }, }, Action: func(c *cli.Context) error { endpointName := c.Args().Get(0) if len(endpointName) == 0 { return cli.NewExitError("endpoint name is required", 1) } public := c.Bool("public") request := api.Endpoint{ Name: endpointName, Public: &public, CertificateID: c.String("certificate-arn"), SslPolicy: c.String("ssl-policy"), } b, err := json.Marshal(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Request("POST", fmt.Sprintf("/districts/%s/endpoints", c.String("district")), bytes.NewBuffer(b)) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.EndpointResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printEndpoint(eResp.Endpoint) return nil }, }, { Name: "show", Usage: "Show endpoint information", ArgsUsage: "ENDPOINT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, }, Action: func(c *cli.Context) error { endpointName := c.Args().Get(0) if len(endpointName) == 0 { return cli.NewExitError("endpoint name is required", 1) } resp, err := api.DefaultClient.Request("GET", fmt.Sprintf("/districts/%s/endpoints/%s", c.String("district"), endpointName), nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.EndpointResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printEndpoint(eResp.Endpoint) return nil }, }, { Name: "list", Usage: "List endpoints", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, }, Action: func(c *cli.Context) error { resp, err := api.DefaultClient.Request("GET", fmt.Sprintf("/districts/%s/endpoints", c.String("district")), nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.EndpointResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printEndpoints(eResp.Endpoints) return nil }, }, { Name: "update", Usage: "Update an endpoint", ArgsUsage: "ENDPOINT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, cli.StringFlag{ Name: "certificate-arn", Usage: "ACM Certificate ARN", }, cli.StringFlag{ Usage: "HTTPS SSL Policy", }, }, Action: func(c *cli.Context) error { endpointName := c.Args().Get(0) if len(endpointName) == 0 { return cli.NewExitError("endpoint name is required", 1) } request := api.Endpoint{ CertificateID: c.String("certificate-arn"), SslPolicy: c.String("ssl-policy"), } b, err := json.Marshal(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Request("PATCH", fmt.Sprintf("/districts/%s/endpoints/%s", c.String("district"), endpointName), bytes.NewBuffer(b)) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.EndpointResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printEndpoint(eResp.Endpoint) return nil }, }, { Name: "delete", Usage: "Delete an endpoint", ArgsUsage: "ENDPOINT_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, cli.BoolFlag{ Name: "no-confirmation", }, }, Action: func(c *cli.Context) error { endpointName := c.Args().Get(0) if len(endpointName) == 0 { return cli.NewExitError("endpoint name is required", 1) } fmt.Printf("You are attempting to delete /%s/endpoints/%s\n", c.String("district"), endpointName) if !c.Bool("no-confirmation") && !utils.AreYouSure("This operation cannot be undone. Are you sure?", utils.NewStdinInputReader()) { return nil } _, err := api.DefaultClient.Request("DELETE", fmt.Sprintf("/districts/%s/endpoints/%s", c.String("district"), endpointName), nil) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, }, }
View Source
var EnvCommand = cli.Command{ Name: "env", Usage: "Environment variable operations", Subcommands: []cli.Command{ { Name: "get", Usage: "Get environment variables", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "heritage-name, H", Usage: "Heritage name", }, }, Action: func(c *cli.Context) error { envName := c.String("environment") heritageName := c.String("heritage-name") if len(envName) > 0 && len(heritageName) > 0 { return cli.NewExitError("environment and heritage-name are exclusive", 1) } if len(envName) > 0 { env, err := LoadEnvironment(c.String("environment")) if err != nil { return cli.NewExitError(err.Error(), 1) } heritageName = env.Name } resp, err := api.DefaultClient.Get("/heritages/"+heritageName, nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var respHeritage api.HeritageResponse err = json.Unmarshal(resp, &respHeritage) if err != nil { return cli.NewExitError(err.Error(), 1) } printEnv(respHeritage.Heritage.EnvVars) return nil }, }, { Name: "set", Usage: "Set environment variables", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "heritage-name, H", Usage: "Heritage name", }, cli.BoolFlag{ Name: "secret, s", Usage: "Save values as secret", }, }, ArgsUsage: "KEY1=VALUE1 [KEY2=VALUE2 ...]", Action: func(c *cli.Context) error { envName := c.String("environment") heritageName := c.String("heritage-name") if len(envName) > 0 && len(heritageName) > 0 { return cli.NewExitError("environment and heritage-name are exclusive", 1) } if len(envName) > 0 { env, err := LoadEnvironment(c.String("environment")) if err != nil { return cli.NewExitError(err.Error(), 1) } heritageName = env.Name } n := c.NArg() if n == 0 { return cli.NewExitError("Specify NAME=VALUE pairs", 1) } pairs := make(map[string]string) for i := 0; i < n; i++ { line := c.Args().Get(i) pair := strings.SplitN(line, "=", 2) pairs[pair[0]] = pair[1] } params := map[string]interface{}{ "env_vars": pairs, "secret": c.Bool("secret"), } j, err := json.Marshal(params) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Post("/heritages/"+heritageName+"/env_vars", bytes.NewBuffer(j)) if err != nil { return cli.NewExitError(err.Error(), 1) } var respHeritage api.HeritageResponse err = json.Unmarshal(resp, &respHeritage) if err != nil { return cli.NewExitError(err.Error(), 1) } printEnv(respHeritage.Heritage.EnvVars) return nil }, }, { Name: "unset", Usage: "Unset environment variables", ArgsUsage: "KEY1 [KEY2 ...]", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "heritage-name, H", Usage: "Heritage name", }, }, Action: func(c *cli.Context) error { envName := c.String("environment") heritageName := c.String("heritage-name") if len(envName) > 0 && len(heritageName) > 0 { return cli.NewExitError("environment and heritage-name are exclusive", 1) } if len(envName) > 0 { env, err := LoadEnvironment(c.String("environment")) if err != nil { return cli.NewExitError(err.Error(), 1) } heritageName = env.Name } params := map[string]interface{}{ "env_keys": c.Args(), } j, err := json.Marshal(params) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Delete("/heritages/"+heritageName+"/env_vars", bytes.NewBuffer(j)) if err != nil { return cli.NewExitError(err.Error(), 1) } var respHeritage api.HeritageResponse err = json.Unmarshal(resp, &respHeritage) if err != nil { return cli.NewExitError(err.Error(), 1) } printEnv(respHeritage.Heritage.EnvVars) return nil }, }, }, }
View Source
var LoginCommand = cli.Command{ Name: "login", Usage: "Login Barcelona", ArgsUsage: "https://endpoint GITHUB_TOKEN", Flags: []cli.Flag{ cli.StringFlag{ Name: "auth, a", Usage: "Auth backend", Value: "github", }, cli.StringFlag{ Name: "github-token", Usage: "GitHub Token", }, cli.StringFlag{ Name: "vault-token", Usage: "Vault Token", }, cli.StringFlag{ Name: "vault-url", Usage: "Vault URL", }, }, Action: func(c *cli.Context) error { endpoint := c.Args().Get(0) backend := c.String("auth") gh_token := c.String("github-token") vault_token := c.String("vault-token") vault_url := c.String("vault-url") ext := struct { utils.UserInputReader *operations.ProxyLoginOperationClient *config.LocalConfig *utils.CommandRunner *utils.FileOps }{ utils.NewStdinInputReader(), &operations.ProxyLoginOperationClient{Client: api.DefaultClient}, config.Get(), &utils.CommandRunner{}, &utils.FileOps{}, } operation := operations.NewLoginOperation(endpoint, backend, gh_token, vault_token, vault_url, ext) return operations.Execute(operation) }, Subcommands: []cli.Command{ { Name: "info", Usage: "Show login information", Action: func(c *cli.Context) error { operation := operations.NewLoginInfoOperation(config.Get().LoadLogin()) return operations.Execute(operation) }, }, }, }
View Source
var NotificationCommand = cli.Command{ Name: "notification", Usage: "Operate notification", Subcommands: []cli.Command{ { Name: "create", Usage: "Create a new notification", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, cli.StringFlag{ Name: "target", Usage: "Notification Target", }, cli.StringFlag{ Name: "endpoint", Usage: "Notification Endpoint", }, }, Action: func(c *cli.Context) error { target := c.String("target") if len(target) == 0 { return cli.NewExitError("target is required", 1) } endpoint := c.String("endpoint") if len(endpoint) == 0 { return cli.NewExitError("endpoint is required", 1) } request := api.Notification{ Target: target, Endpoint: endpoint, } b, err := json.Marshal(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Request("POST", fmt.Sprintf("/districts/%s/notifications", c.String("district")), bytes.NewBuffer(b)) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.NotificationResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printNotification(eResp.Notification) return nil }, }, { Name: "show", Usage: "Show notification", ArgsUsage: "ID", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, }, Action: func(c *cli.Context) error { id, err := parseIDArg(c) if err != nil { return err } resp, err := api.DefaultClient.Request("GET", fmt.Sprintf("/districts/%s/notifications/%d", c.String("district"), id), nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.NotificationResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printNotification(eResp.Notification) return nil }, }, { Name: "update", Usage: "Update notification", ArgsUsage: "ID", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, cli.StringFlag{ Name: "target", Usage: "Notification Target", }, cli.StringFlag{ Name: "endpoint", Usage: "Notification Endpoint", }, }, Action: func(c *cli.Context) error { id, err := parseIDArg(c) if err != nil { return err } request := api.Notification{ ID: id, Target: c.String("target"), Endpoint: c.String("endpoint"), } b, err := json.Marshal(&request) if err != nil { return cli.NewExitError(err.Error(), 1) } fmt.Println(string(b)) resp, err := api.DefaultClient.Request("PATCH", fmt.Sprintf("/districts/%s/notifications/%d", c.String("district"), id), bytes.NewBuffer(b)) if err != nil { return cli.NewExitError(err.Error(), 1) } var eResp api.NotificationResponse err = json.Unmarshal(resp, &eResp) if err != nil { return cli.NewExitError(err.Error(), 1) } printNotification(eResp.Notification) return nil }, }, { Name: "delete", Usage: "Delete notification", ArgsUsage: "ID", Flags: []cli.Flag{ cli.StringFlag{ Name: "district, d", Value: "default", Usage: "District name", }, }, Action: func(c *cli.Context) error { id, err := parseIDArg(c) if err != nil { return err } _, err = api.DefaultClient.Request("DELETE", fmt.Sprintf("/districts/%s/notifications/%d", c.String("district"), id), nil) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, }, }
View Source
var ReleaseCommand = cli.Command{ Name: "release", Usage: "Manipulate releases", Subcommands: []cli.Command{ { Name: "list", Usage: "List releases", Action: func(c *cli.Context) error { return nil }, }, { Name: "rollback", Usage: "Roll back to the previous release", Action: func(c *cli.Context) error { return nil }, }, }, }
View Source
var ReviewCommand = cli.Command{ Name: "review", Usage: "Review Apps", Subcommands: []cli.Command{ { Name: "deploy", ArgsUsage: "SUBJECT", Flags: []cli.Flag{ cli.StringFlag{ Name: "tag, t", Usage: "Tag of docker image", }, cli.StringFlag{ Name: "token", Usage: "review group token", }, cli.StringFlag{ Name: "retention, r", }, }, Action: func(c *cli.Context) error { subject := c.Args().Get(0) tag := c.String("tag") token := c.String("token") retention := c.String("retention") var retentionSec int if len(retention) == 0 { retentionSec = 24 * 3600 } else { d, err := time.ParseDuration(retention) if err != nil { return cli.NewExitError(err.Error(), 1) } retentionSec = int(d.Seconds()) } reviewDef, err := LoadReviewDefinition() if err != nil { return cli.NewExitError(err.Error(), 1) } com := DeployReviewApp{ Request: &api.ReviewAppRequest{ ReviewAppDefinition: reviewDef, Subject: subject, Retention: retentionSec, ImageTag: tag, }, Token: token, } return com.Execute() }, }, { Name: "delete", ArgsUsage: "REVIEWAPP_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "group", Usage: "Review group name", }, cli.StringFlag{ Name: "token", Usage: "review group token", }, }, Action: func(c *cli.Context) error { name := c.Args().Get(0) token := c.String("token") groupName := c.String("group") var err error if len(token) == 0 { _, err = api.DefaultClient.Delete("/review_groups/"+groupName+"/apps/"+name, nil) } else { _, err = api.DefaultClient.Delete("/review_groups/"+groupName+"/ci/apps/"+token+"/"+name, nil) } if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "list", Flags: []cli.Flag{ cli.StringFlag{ Name: "group", Usage: "Review group name", }, }, Action: func(c *cli.Context) error { groupName := c.String("group") if len(groupName) == 0 { reviewDef, err := LoadReviewDefinition() if err != nil { return cli.NewExitError(err.Error(), 1) } groupName = reviewDef.GroupName } resp, err := api.DefaultClient.Get("/review_groups/"+groupName+"/apps", nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var appResp api.ReviewAppResponse err = json.Unmarshal(resp, &appResp) if err != nil { return cli.NewExitError(err.Error(), 1) } renderApps(appResp.ReviewApps) return nil }, }, ReviewGroupCommand, }, }
View Source
var ReviewGroupCommand = cli.Command{ Name: "group", Subcommands: []cli.Command{ { Name: "create", ArgsUsage: "GROUP_NAME", Flags: []cli.Flag{ cli.StringFlag{ Name: "base-domain", Usage: "Base Domain Name", }, cli.StringFlag{ Name: "endpoint", Usage: "Endpoint name", }, }, Action: func(c *cli.Context) error { name := c.Args().Get(0) if len(name) == 0 { return cli.NewExitError("Group name is required", 1) } req := api.ReviewGroupRequest{ Name: name, BaseDomain: c.String("base-domain"), EndpointName: c.String("endpoint"), } j, err := json.Marshal(req) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Post("/review_groups", bytes.NewBuffer(j)) if err != nil { return cli.NewExitError(err.Error(), 1) } var rResp api.ReviewGroupResponse err = json.Unmarshal(resp, &rResp) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, { Name: "show", ArgsUsage: "GROUP_NAME", Action: func(c *cli.Context) error { groupName := c.Args().Get(0) resp, err := api.DefaultClient.Get("/review_groups/"+groupName, nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var rResp api.ReviewGroupResponse err = json.Unmarshal(resp, &rResp) group := rResp.ReviewGroup fmt.Println("Name: ", group.Name) fmt.Println("Base Domain: ", group.BaseDomain) fmt.Println("Endpoint: ", group.Endpoint.Name) fmt.Println("Token: ", *group.Token) fmt.Println("Apps") return nil }, }, { Name: "list", Action: func(c *cli.Context) error { resp, err := api.DefaultClient.Get("/review_groups", nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var rResp api.ReviewGroupResponse err = json.Unmarshal(resp, &rResp) if err != nil { return cli.NewExitError(err.Error(), 1) } groups := rResp.ReviewGroups table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"Name", "Base Domain", "Endpoint"}) table.SetBorder(false) for _, g := range groups { table.Append([]string{g.Name, g.BaseDomain, g.Endpoint.Name}) } table.Render() return nil }, }, { Name: "delete", ArgsUsage: "GROUP_NAME", Action: func(c *cli.Context) error { groupName := c.Args().Get(0) _, err := api.DefaultClient.Delete("/review_groups/"+groupName, nil) if err != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }, }, }
View Source
var RunCommand = cli.Command{ Name: "run", Usage: "Run command inside Barcelona environment", ArgsUsage: "COMMAND...", Flags: []cli.Flag{ cli.StringFlag{ Name: "environment, e", Usage: "Environment of heritage", }, cli.StringFlag{ Name: "heritage-name, H", Usage: "Heritage name", }, cli.IntFlag{ Name: "memory, m", Usage: "Memory size in MB", }, cli.StringFlag{ Name: "user, u", Usage: "User name", }, cli.BoolFlag{ Name: "detach, D", Usage: "Detach mode", }, cli.StringSliceFlag{ Name: "envvar, E", Usage: "Environment variable to pass to task", }, }, Action: func(c *cli.Context) error { envName := c.String("environment") heritageName := c.String("heritage-name") detach := c.Bool("detach") envVars := c.StringSlice("envvar") envVarMap, loadEnvVarMapErr := loadEnvVars(envName) if loadEnvVarMapErr != nil { return cli.NewExitError(loadEnvVarMapErr.Error(), 1) } if len(envName) > 0 && len(heritageName) > 0 { return cli.NewExitError("environment and heritage-name are exclusive", 1) } if len(heritageName) == 0 { env, err := LoadEnvironment(envName) if err != nil { return cli.NewExitError(err.Error(), 1) } heritageName = env.Name } if len(envVars) > 0 { varmap, err := checkEnvVars(envVars) if err != nil { return cli.NewExitError(err.Error(), 1) } for k, v := range varmap { envVarMap[k] = v } } if len(c.Args()) == 0 { return cli.NewExitError("Command is required", 1) } command := strings.Join(c.Args(), " ") params := map[string]interface{}{ "interactive": !detach, "command": command, "env_vars": envVarMap, } memory := c.Int("memory") if memory > 0 { params["memory"] = memory } user := c.String("user") if user != "" { params["user"] = user } j, err := json.Marshal(params) if err != nil { return cli.NewExitError(err.Error(), 1) } resp, err := api.DefaultClient.Post("/heritages/"+heritageName+"/oneoffs", bytes.NewBuffer(j)) if err != nil { return cli.NewExitError(err.Error(), 1) } var respOneoff api.OneoffResponse err = json.Unmarshal(resp, &respOneoff) if err != nil { return cli.NewExitError(err.Error(), 1) } oneoff := respOneoff.Oneoff certificate := respOneoff.Certificate if detach { PrintOneoff(oneoff) return nil } fmt.Println("Waiting for the process to start") LOOP: for { path := fmt.Sprintf("/oneoffs/%d", oneoff.ID) resp, err := api.DefaultClient.Get(path, nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var respOneoff api.OneoffResponse err = json.Unmarshal(resp, &respOneoff) if err != nil { return cli.NewExitError(err.Error(), 1) } switch respOneoff.Oneoff.Status { case "RUNNING": break LOOP case "PENDING": time.Sleep(3 * time.Second) default: return cli.NewExitError("Unexpected task status "+respOneoff.Oneoff.Status, 1) } } fmt.Println("Connecting to the process") var matchedCI *api.ContainerInstance for _, ci := range oneoff.District.ContainerInstances { if ci.ContainerInstanceArn == oneoff.ContainerInstanceARN { matchedCI = ci break } } ssh := SSH{ IP: matchedCI.PrivateIPAddress, BastionIP: oneoff.District.BastionIP, Certificate: certificate, } if ssh.Run(oneoff.InteractiveRunCommand) != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }
View Source
var SSHCommand = cli.Command{ Name: "ssh", Usage: "SSH into Barcelona container instance", ArgsUsage: "DISTRICT_NAME CONTAINER_INSTANCE_PRIVATE_IP", Action: func(c *cli.Context) error { districtName := c.Args().Get(0) if len(districtName) == 0 { return cli.NewExitError("district name is required", 1) } ip := c.Args().Get(1) if len(ip) == 0 { return cli.NewExitError("ip is required", 1) } resp, err := api.DefaultClient.Post("/districts/"+districtName+"/sign_public_key", nil) if err != nil { return cli.NewExitError(err.Error(), 1) } var districtResp api.DistrictResponse err = json.Unmarshal(resp, &districtResp) if err != nil { return cli.NewExitError(err.Error(), 1) } ssh := SSH{ IP: ip, BastionIP: districtResp.District.BastionIP, Certificate: districtResp.Certificate, } if ssh.Run("") != nil { return cli.NewExitError(err.Error(), 1) } return nil }, }
Functions ¶
func LoadReviewDefinition ¶ added in v0.9.1
func LoadReviewDefinition() (*api.ReviewAppDefinition, error)
func PrintOneoff ¶ added in v0.9.1
Types ¶
type DeployReviewApp ¶ added in v0.9.1
type DeployReviewApp struct { Request *api.ReviewAppRequest Response *api.ReviewAppResponse Token string }
func (*DeployReviewApp) Execute ¶ added in v0.9.1
func (com *DeployReviewApp) Execute() error
type HeritageConfig ¶
type HeritageConfig struct { Environments map[string]*api.Heritage `yaml:"environments" json:"environments"` Review *api.ReviewAppDefinition `yaml:"review" json:"review"` }
Click to show internal directories.
Click to hide internal directories.