From ccbcc2607a3fafaa760586115141fbc1f13a937a Mon Sep 17 00:00:00 2001 From: fabriciojs Date: Fri, 5 May 2023 09:30:37 -0300 Subject: [PATCH 1/3] wip: flags --- commands/cloud_deploy.go | 73 ++++++++++++++++++++++++++++++++---- services/cloud/api/deploy.go | 5 ++- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/commands/cloud_deploy.go b/commands/cloud_deploy.go index 7438d10f..f34abb0e 100644 --- a/commands/cloud_deploy.go +++ b/commands/cloud_deploy.go @@ -21,17 +21,30 @@ const ( koolDeployFile = "kool.deploy.yml" ) +// KoolCloudDeployFlags holds the flags for the kool cloud deploy command +type KoolCloudDeployFlags struct { + Token string // env: KOOL_API_TOKEN + Timeout uint // env: KOOL_API_TIMEOUT + WwwRedirect bool // env: KOOL_DEPLOY_WWW_REDIRECT + DeployDomain string // env: KOOL_DEPLOY_DOMAIN + DeployDomainExtras []string // env: KOOL_DEPLOY_DOMAIN_EXTRAS + + // Cluster string // env: KOOL_DEPLOY_CLUSTER + // env: KOOL_API_URL +} + // KoolDeploy holds handlers and functions for using Deploy API type KoolDeploy struct { DefaultKoolService - env environment.EnvStorage - git builder.Command + flags *KoolCloudDeployFlags + env environment.EnvStorage + git builder.Command } // NewDeployCommand initializes new kool deploy Cobra command -func NewDeployCommand(deploy *KoolDeploy) *cobra.Command { - return &cobra.Command{ +func NewDeployCommand(deploy *KoolDeploy) (cmd *cobra.Command) { + cmd = &cobra.Command{ Use: "deploy", Short: "Deploy a local application to a Kool Cloud environment", RunE: DefaultCommandRunFunction(deploy), @@ -39,6 +52,14 @@ func NewDeployCommand(deploy *KoolDeploy) *cobra.Command { DisableFlagsInUseLine: true, } + + cmd.Flags().StringVarP(&deploy.flags.Token, "token", "", "", "Token to authenticate with Kool Cloud API") + cmd.Flags().StringVarP(&deploy.flags.DeployDomain, "domain", "", "", "Environment domain name to deploy to") + cmd.Flags().UintVarP(&deploy.flags.Timeout, "timeout", "", 0, "Timeout in minutes for waiting the deployment to finish") + cmd.Flags().StringArrayVarP(&deploy.flags.DeployDomainExtras, "domain-extra", "", []string{}, "List of extra domain aliases") + cmd.Flags().BoolVarP(&deploy.flags.WwwRedirect, "www-redirect", "", false, "Redirect www to non-www domain") + + return } // NewKoolDeploy creates a new pointer with default KoolDeploy service @@ -46,8 +67,8 @@ func NewDeployCommand(deploy *KoolDeploy) *cobra.Command { func NewKoolDeploy() *KoolDeploy { return &KoolDeploy{ *newDefaultKoolService(), + &KoolCloudDeployFlags{}, environment.NewEnvStorage(), - builder.NewCommand("git"), } } @@ -88,9 +109,11 @@ func (d *KoolDeploy) Execute(args []string) (err error) { d.Shell().Println("Going to deploy...") - timeout := 30 * time.Minute + timeout := 15 * time.Minute - if min, err := strconv.Atoi(d.env.Get("KOOL_API_TIMEOUT")); err == nil { + if d.flags.Timeout > 0 { + timeout = time.Duration(d.flags.Timeout) * time.Minute + } else if min, err := strconv.Atoi(d.env.Get("KOOL_API_TIMEOUT")); err == nil { timeout = time.Duration(min) * time.Minute } @@ -252,7 +275,41 @@ func (d *KoolDeploy) handleDeployEnv(files []string) []string { } func (d *KoolDeploy) validate() (err error) { - err = cloud.ValidateKoolDeployFile(d.env.Get("PWD"), koolDeployFile) + if err = cloud.ValidateKoolDeployFile(d.env.Get("PWD"), koolDeployFile); err != nil { + return + } + + // if no domain is set, we try to get it from the environment + if d.flags.DeployDomain == "" && d.env.Get("KOOL_DEPLOY_DOMAIN") == "" { + err = fmt.Errorf("Missing deploy domain. Please set it via --domain or KOOL_DEPLOY_DOMAIN environment variable.") + return + } else if d.flags.DeployDomain != "" { + // shares the flag via environment variable + d.env.Set("KOOL_DEPLOY_DOMAIN", d.flags.DeployDomain) + } + + // if no token is set, we try to get it from the environment + if d.flags.Token == "" && d.env.Get("KOOL_API_TOKEN") == "" { + err = fmt.Errorf("Missing Kool Cloud API token. Please set it via --token or KOOL_API_TOKEN environment variable.") + return + } else if d.flags.Token != "" { + d.env.Set("KOOL_API_TOKEN", d.flags.Token) + } + + // share the www-redirection flag via environment variable + if d.flags.WwwRedirect { + d.env.Set("KOOL_DEPLOY_WWW_REDIRECT", "true") + } + + // share the domain extras via environment variable + if len(d.flags.DeployDomainExtras) > 0 { + d.env.Set("KOOL_DEPLOY_DOMAIN_EXTRAS", strings.Join(d.flags.DeployDomainExtras, ",")) + } + + // TODO: make a call to the cloud API to validate the config + // - validate the token is valid + // - validate the domain is valid / the token gives access to it + // - validate the domain extras are valid / the token gives access to them return } diff --git a/services/cloud/api/deploy.go b/services/cloud/api/deploy.go index 96aaac2d..0a16f56f 100644 --- a/services/cloud/api/deploy.go +++ b/services/cloud/api/deploy.go @@ -63,7 +63,8 @@ func (d *Deploy) SendFile() (err error) { if errAPI.Status == http.StatusUnauthorized { err = ErrUnauthorized } else if errAPI.Status == http.StatusUnprocessableEntity { - fmt.Println(err) + fmt.Println(errAPI.Message) + fmt.Println(errAPI.Errors) err = ErrPayloadValidation } else if errAPI.Status != http.StatusOK && errAPI.Status != http.StatusCreated { err = ErrBadResponseStatus @@ -74,7 +75,7 @@ func (d *Deploy) SendFile() (err error) { d.id = fmt.Sprintf("%d", resp.ID) if d.id == "0" { - err = errors.New("unexpected API response, please ask for support") + err = errors.New("unexpected API response, please reach out for support on Slack or Github") } return From f81dd6febf3591ef7caabe7509e8d09f53e72cfd Mon Sep 17 00:00:00 2001 From: fabriciojs Date: Fri, 5 May 2023 11:38:47 -0300 Subject: [PATCH 2/3] setup devcontainer --- .devcontainer/Dockerfile | 21 ++++++++++++++++++ .devcontainer/devcontainer.json | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..b0295008 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,21 @@ +FROM debian:stable + +ARG USERNAME=kool +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -s /bin/bash -m $USERNAME \ + && apt-get update \ + && apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# install kool +RUN apt update && apt install curl git -y && curl -fsSL https://kool.dev/install | bash + +WORKDIR /home/kool + +USER $USERNAME + +RUN bash -c "$(curl -fsSL https://raw.githubusercontent.com/ohmybash/oh-my-bash/master/tools/install.sh)" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..e21382a2 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile +{ + "name": "Kool.dev Container for Go CLI development", + + "build": { + "context": ".", + "dockerfile": "Dockerfile" + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}, + "ghcr.io/devcontainers/features/go:1": { + "version": "1.19" + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [ + // ], + + // Uncomment the next line to run commands after the container is created. + "postCreateCommand": [ + // "bash -c \"$(curl -fsSL https://raw.githubusercontent.com/ohmybash/oh-my-bash/master/tools/install.sh)\"" + ], + + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.go" + ] + } + }, + + // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "kool" +} From cbe7a833072749c494f13bb1514014c97eaeae57 Mon Sep 17 00:00:00 2001 From: fabriciojs Date: Fri, 8 Sep 2023 22:51:49 -0300 Subject: [PATCH 3/3] fix test --- commands/cloud_deploy_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/commands/cloud_deploy_test.go b/commands/cloud_deploy_test.go index 2bc9b23b..9957dfc8 100644 --- a/commands/cloud_deploy_test.go +++ b/commands/cloud_deploy_test.go @@ -25,6 +25,10 @@ func TestNewKoolDeploy(t *testing.T) { func fakeKoolDeploy() *KoolDeploy { return &KoolDeploy{ *(newDefaultKoolService().Fake()), + &KoolCloudDeployFlags{ + DeployDomain: "foo", + Token: "bar", + }, environment.NewFakeEnvStorage(), &builder.FakeCommand{}, }