Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kool cloud deploy flags #465

Merged
merged 5 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading