Skip to content

Commit

Permalink
Merge pull request #465 from kool-dev/deploy-args
Browse files Browse the repository at this point in the history
kool cloud deploy flags
  • Loading branch information
fabriciojs authored Sep 9, 2023
2 parents 0ccebd2 + cbe7a83 commit a2a2f38
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 10 deletions.
21 changes: 21 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -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)"
39 changes: 39 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -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"
}
73 changes: 65 additions & 8 deletions commands/cloud_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,54 @@ const (
koolDeployFile = "kool.cloud.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),
Args: cobra.NoArgs,

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
// dependencies.
func NewKoolDeploy() *KoolDeploy {
return &KoolDeploy{
*newDefaultKoolService(),
&KoolCloudDeployFlags{},
environment.NewEnvStorage(),

builder.NewCommand("git"),
}
}
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
4 changes: 4 additions & 0 deletions commands/cloud_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{},
}
Expand Down
5 changes: 3 additions & 2 deletions services/cloud/api/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit a2a2f38

Please sign in to comment.