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

feat: add helm cancel and helm deploy cmd #223

Merged
merged 1 commit into from
Dec 20, 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
3 changes: 3 additions & 0 deletions cmd/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
var helmName string
var helmNames string
var targetHelmName string
var chartVersion string
var chartGitCommitId string
var valuesOverrideCommitId string

var helmCmd = &cobra.Command{
Use: "helm",
Expand Down
77 changes: 77 additions & 0 deletions cmd/helm_cancel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cmd

import (
"context"
"fmt"
"github.com/pterm/pterm"
"github.com/qovery/qovery-cli/utils"
"github.com/spf13/cobra"
"os"
)

var helmCancelCmd = &cobra.Command{
Use: "cancel",
Short: "Cancel a helm deployment",
Run: func(cmd *cobra.Command, args []string) {
utils.Capture(cmd)

tokenType, token, err := utils.GetAccessToken()
if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

client := utils.GetQoveryClient(tokenType, token)
_, _, envId, err := getOrganizationProjectEnvironmentContextResourcesIds(client)

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

helms, _, err := client.HelmsAPI.ListHelms(context.Background(), envId).Execute()

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

helm := utils.FindByHelmName(helms.GetResults(), helmName)

if helm == nil {
utils.PrintlnError(fmt.Errorf("helm %s not found", helmName))
utils.PrintlnInfo("You can list all helms with: qovery helm list")
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

msg, err := utils.CancelServiceDeployment(client, envId, helm.Id, utils.HelmType, watchFlag)

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

if msg != "" {
utils.PrintlnInfo(msg)
return
}

utils.Println(fmt.Sprintf("helm %s deployment cancelled!", pterm.FgBlue.Sprintf(helmName)))
},
}

func init() {
helmCmd.AddCommand(helmCancelCmd)
helmCancelCmd.Flags().StringVarP(&organizationName, "organization", "", "", "Organization Name")
helmCancelCmd.Flags().StringVarP(&projectName, "project", "", "", "Project Name")
helmCancelCmd.Flags().StringVarP(&environmentName, "environment", "", "", "Environment Name")
helmCancelCmd.Flags().StringVarP(&helmName, "helm", "n", "", "Helm Name")
helmCancelCmd.Flags().BoolVarP(&watchFlag, "watch", "w", false, "Watch cancel until it's done or an error occurs")

_ = helmCancelCmd.MarkFlagRequired("helm")
}
149 changes: 149 additions & 0 deletions cmd/helm_deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package cmd

import (
"context"
"fmt"
"github.com/pterm/pterm"
"github.com/qovery/qovery-client-go"
"time"

"github.com/qovery/qovery-cli/utils"
"github.com/spf13/cobra"
"os"
)

var helmDeployCmd = &cobra.Command{
Use: "deploy",
Short: "Deploy a helm",
Run: func(cmd *cobra.Command, args []string) {
utils.Capture(cmd)

tokenType, token, err := utils.GetAccessToken()
if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

if helmName == "" && helmNames == "" {
utils.PrintlnError(fmt.Errorf("use either --helm \"<helm name>\" or --helms \"<helm1 name>, <helm2 name>\" but not both at the same time"))
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

if helmName != "" && helmNames != "" {
utils.PrintlnError(fmt.Errorf("you can't use --helm and --helms at the same time"))
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

client := utils.GetQoveryClient(tokenType, token)
_, _, envId, err := getOrganizationProjectEnvironmentContextResourcesIds(client)

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

if helmNames != "" {
// wait until service is ready
for {
if utils.IsEnvironmentInATerminalState(envId, client) {
break
}

utils.Println(fmt.Sprintf("Waiting for environment %s to be ready..", pterm.FgBlue.Sprintf(envId)))
time.Sleep(5 * time.Second)
}

// deploy multiple services
err := utils.DeployHelms(client, envId, helmNames, chartVersion, chartGitCommitId, valuesOverrideCommitId)

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

utils.Println(fmt.Sprintf("Deploying helms %s in progress..", pterm.FgBlue.Sprintf(helmNames)))

if watchFlag {
utils.WatchEnvironment(envId, "unused", client)
}

return
}

helms, _, err := client.HelmsAPI.ListHelms(context.Background(), envId).Execute()

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

helm := utils.FindByHelmName(helms.GetResults(), helmName)

if helm == nil {
utils.PrintlnError(fmt.Errorf("helm %s not found", helmName))
utils.PrintlnInfo("You can list all helms with: qovery helm list")
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

var mCommitId *string
var mChartVersion *string
var mValuesOverrideCommitId *string
if chartGitCommitId != "" {
mCommitId = &chartGitCommitId
}

if chartVersion != "" {
mChartVersion = &chartVersion
}

if valuesOverrideCommitId != "" {
mValuesOverrideCommitId = &valuesOverrideCommitId
}


req := qovery.HelmDeployRequest{
ChartVersion: mChartVersion,
GitCommitId: mCommitId,
ValuesOverrideGitCommitId: mValuesOverrideCommitId,
}

msg, err := utils.DeployService(client, envId, helm.Id, utils.HelmType, req, watchFlag)

if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

if msg != "" {
utils.PrintlnInfo(msg)
return
}

if watchFlag {
utils.Println(fmt.Sprintf("helm %s deployed!", pterm.FgBlue.Sprintf(helmName)))
} else {
utils.Println(fmt.Sprintf("Deploying helm %s in progress..", pterm.FgBlue.Sprintf(helmName)))
}
},
}

func init() {
helmCmd.AddCommand(helmDeployCmd)
helmDeployCmd.Flags().StringVarP(&organizationName, "organization", "", "", "Organization Name")
helmDeployCmd.Flags().StringVarP(&projectName, "project", "", "", "Project Name")
helmDeployCmd.Flags().StringVarP(&environmentName, "environment", "", "", "Environment Name")
helmDeployCmd.Flags().StringVarP(&helmName, "helm", "n", "", "helm Name")
helmDeployCmd.Flags().StringVarP(&helmNames, "helms", "", "", "helm Names (comma separated) (ex: --helms \"helm1,helm2\")")
helmDeployCmd.Flags().StringVarP(&chartVersion, "chart_version", "", "", "helm chart version")
helmDeployCmd.Flags().StringVarP(&chartGitCommitId, "chart_git_commit_id", "", "", "helm chart git commit id")
helmDeployCmd.Flags().StringVarP(&valuesOverrideCommitId, "values_override_git_commit_id", "", "", "helm values override git commit id")
helmDeployCmd.Flags().BoolVarP(&watchFlag, "watch", "w", false, "Watch helm status until it's ready or an error occurs")
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a
github.com/pterm/pterm v0.12.55
github.com/qovery/qovery-client-go v0.0.0-20231218142939-5f77c5a27bb7
github.com/qovery/qovery-client-go v0.0.0-20231219130711-1b52194296f5
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.6.1
github.com/spf13/pflag v1.0.5
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ github.com/qovery/qovery-client-go v0.0.0-20231218100840-79b5831d4fc2 h1:fO+LVI9
github.com/qovery/qovery-client-go v0.0.0-20231218100840-79b5831d4fc2/go.mod h1:5QD7sC1Z6XCCYd31c4XKVwGdEOjvtgG0NDcaVDoWb+o=
github.com/qovery/qovery-client-go v0.0.0-20231218142939-5f77c5a27bb7 h1:FukfJyZOIuYCJgyqh96DpQshcEAzWP65WhhMCAeiIeg=
github.com/qovery/qovery-client-go v0.0.0-20231218142939-5f77c5a27bb7/go.mod h1:5QD7sC1Z6XCCYd31c4XKVwGdEOjvtgG0NDcaVDoWb+o=
github.com/qovery/qovery-client-go v0.0.0-20231219130711-1b52194296f5 h1:uTmfOdyWH7/Ldf/LT3X/P0OlBg9J8Pe9PWR8MbdaWao=
github.com/qovery/qovery-client-go v0.0.0-20231219130711-1b52194296f5/go.mod h1:5QD7sC1Z6XCCYd31c4XKVwGdEOjvtgG0NDcaVDoWb+o=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand Down
114 changes: 113 additions & 1 deletion utils/qovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,6 @@ func DeployJobs(client *qovery.APIClient, envId string, jobNames string, commitI

return deployAllServices(client, envId, req)
}

func GetJobDocker(job *qovery.JobResponse) *qovery.BaseJobResponseAllOfSourceOneOf1Docker {
if job.CronJobResponse.Source.BaseJobResponseAllOfSourceOneOf1 != nil {
return job.CronJobResponse.Source.BaseJobResponseAllOfSourceOneOf1.Docker
Expand Down Expand Up @@ -1537,6 +1536,92 @@ func DeployDatabases(client *qovery.APIClient, envId string, databaseNames strin
return deployAllServices(client, envId, req)
}

func DeployHelms(client *qovery.APIClient, envId string, helmNames string, chartVersion string, chartGitCommitId string, valuesOverrideCommitId string) error {
if helmNames == "" {
return nil
}

var helmsToDeploy []qovery.DeployAllRequestHelmsInner

helms, _, err := client.HelmsAPI.ListHelms(context.Background(), envId).Execute()

if err != nil {
return err
}

for _, helmName := range strings.Split(helmNames, ",") {
trimmedHelmName := strings.TrimSpace(helmName)
helm := FindByHelmName(helms.GetResults(), trimmedHelmName)

if helm == nil {
return fmt.Errorf("helm %s not found", trimmedHelmName)
}


var gitSource = GetGitSource(helm)
var helmRepositorySource = GetHelmRepository(helm)

if gitSource != nil && helmRepositorySource != nil {
return fmt.Errorf("invalid helm")
}

var mCommitId *string
var mChartVersion *string
var mValuesOverrideCommitId *string

if gitSource != nil {
if chartGitCommitId != "" {
mCommitId = &chartGitCommitId
}
}

if helmRepositorySource != nil {
if chartVersion != "" {
mChartVersion = &chartVersion
}
}

if valuesOverrideCommitId != "" {
mValuesOverrideCommitId = &valuesOverrideCommitId
}


helmsToDeploy = append(helmsToDeploy, qovery.DeployAllRequestHelmsInner{
Id: &helm.Id,
ChartVersion: mChartVersion,
GitCommitId: mCommitId,
ValuesOverrideGitCommitId: mValuesOverrideCommitId,
})
}

req := qovery.DeployAllRequest{
Applications: nil,
Databases: nil,
Containers: nil,
Jobs: nil,
Helms: helmsToDeploy,
}

return deployAllServices(client, envId, req)
}


func GetGitSource(helm *qovery.HelmResponse) *qovery.ApplicationGitRepositoryRequest {
if helm.Source.HelmResponseAllOfSourceOneOf != nil && helm.Source.HelmResponseAllOfSourceOneOf.Git != nil {
return helm.Source.HelmResponseAllOfSourceOneOf.Git.GitRepository
}

return nil
}

func GetHelmRepository(helm *qovery.HelmResponse) *qovery.HelmResponseAllOfSourceOneOf1Repository {
if helm.Source.HelmResponseAllOfSourceOneOf1 != nil {
return helm.Source.HelmResponseAllOfSourceOneOf1.Repository
}

return nil
}

func deployAllServices(client *qovery.APIClient, envId string, req qovery.DeployAllRequest) error {
_, _, err := client.EnvironmentActionsAPI.DeployAllServices(context.Background(), envId).DeployAllRequest(req).Execute()
if err != nil {
Expand Down Expand Up @@ -1631,6 +1716,17 @@ func CancelServiceDeployment(client *qovery.APIClient, envId string, serviceId s
return "", err
}

return "", nil
}
}
case HelmType:
for _, helm := range statuses.GetHelms() {
if helm.Id == serviceId && !IsTerminalState(helm.State) {
err := CancelEnvironmentDeployment(client, envId, watchFlag)
if err != nil {
return "", err
}

return "", nil
}
}
Expand Down Expand Up @@ -1931,6 +2027,22 @@ func DeployService(client *qovery.APIClient, envId string, serviceId string, ser
WatchJob(serviceId, envId, client)
}

return "", nil
}
}
case HelmType:
for _, helm := range statuses.GetHelms() {
if helm.Id == serviceId && IsTerminalState(helm.State) {
req := request.(qovery.HelmDeployRequest)
_, _, err := client.HelmActionsAPI.DeployHelm(context.Background(), serviceId).HelmDeployRequest(req).Execute()
if err != nil {
return "", toHttpResponseError(resp)
}

if watchFlag {
WatchHelm(serviceId, envId, client)
}

return "", nil
}
}
Expand Down
Loading