diff --git a/cmd/admin.go b/cmd/admin.go index 5cc15a29..d3146dcd 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -21,6 +21,7 @@ var ( rootDns string additionalClaims string description string + lockTtlInDays int32 adminCmd = &cobra.Command{Use: "admin", Hidden: true} ) diff --git a/cmd/admin_lock.go b/cmd/admin_lock.go deleted file mode 100644 index 4de73224..00000000 --- a/cmd/admin_lock.go +++ /dev/null @@ -1,33 +0,0 @@ -package cmd - -import ( - "github.com/qovery/qovery-cli/pkg" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var ( - adminLockByIdCmd = &cobra.Command{ - Use: "lock", - Short: "Lock a cluster with its Id", - Run: func(cmd *cobra.Command, args []string) { - lockClusterById() - }, - } -) - -func init() { - adminLockByIdCmd.Flags().StringVarP(&clusterId, "cluster", "c", "", "Cluster's id") - adminLockByIdCmd.Flags().StringVarP(&lockReason, "reason", "r", "", "Lock reason") - orgaErr = adminLockByIdCmd.MarkFlagRequired("cluster") - orgaErr = adminLockByIdCmd.MarkFlagRequired("reason") - adminCmd.AddCommand(adminLockByIdCmd) -} - -func lockClusterById() { - if orgaErr != nil { - log.Error("Invalid cluster Id") - } else { - pkg.LockById(clusterId, lockReason) - } -} diff --git a/cmd/admin_unlock.go b/cmd/admin_unlock.go deleted file mode 100644 index 0f7ec1bc..00000000 --- a/cmd/admin_unlock.go +++ /dev/null @@ -1,31 +0,0 @@ -package cmd - -import ( - "github.com/qovery/qovery-cli/pkg" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var ( - adminUnlockByIdCmd = &cobra.Command{ - Use: "unlock", - Short: "Unlock a cluster with its Id", - Run: func(cmd *cobra.Command, args []string) { - unlockClusterById() - }, - } -) - -func init() { - adminUnlockByIdCmd.Flags().StringVarP(&clusterId, "cluster", "c", "", "Cluster's id") - orgaErr = adminUnlockByIdCmd.MarkFlagRequired("cluster") - adminCmd.AddCommand(adminUnlockByIdCmd) -} - -func unlockClusterById() { - if orgaErr != nil { - log.Error("Invalid cluster Id") - } else { - pkg.UnockById(clusterId) - } -} diff --git a/cmd/cluster_lock.go b/cmd/cluster_lock.go new file mode 100644 index 00000000..5b85e220 --- /dev/null +++ b/cmd/cluster_lock.go @@ -0,0 +1,63 @@ +package cmd + +import ( + "context" + "fmt" + "github.com/qovery/qovery-cli/utils" + "github.com/qovery/qovery-client-go" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "io" + "os" +) + +var clusterLockCmd = &cobra.Command{ + Use: "lock", + Short: "Lock a cluster", + Run: func(cmd *cobra.Command, args []string) { + lockCluster() + }, +} + +func init() { + clusterLockCmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Cluster ID") + clusterLockCmd.Flags().StringVarP(&lockReason, "reason", "r", "", "Reason") + clusterLockCmd.Flags().Int32VarP(&lockTtlInDays, "ttl-in-days", "d", -1, "TTL in days") + + clusterLockCmd.MarkFlagRequired("cluster-id") + clusterLockCmd.MarkFlagRequired("reason") + + clusterCmd.AddCommand(clusterLockCmd) +} + +func lockCluster() { + var ttlInDays *int32 = nil + if lockTtlInDays != -1 { + ttlInDays = &lockTtlInDays + } + + if utils.Validate("lock") { + tokenType, token, err := utils.GetAccessToken() + if err != nil { + utils.PrintlnError(err) + os.Exit(1) + } + + client := utils.GetQoveryClient(tokenType, token) + + lockClusterRequest := qovery.ClusterLockRequest{ + Reason: lockReason, + TtlInDays: ttlInDays, + } + + _, http, err := client.ClustersAPI.LockCluster(context.Background(), clusterId).ClusterLockRequest(lockClusterRequest).Execute() + if err != nil { + utils.PrintlnError(err) + result, _ := io.ReadAll(http.Body) + log.Error("%s", string(result)) + os.Exit(1) + } else { + fmt.Println("Cluster locked.") + } + } +} diff --git a/cmd/cluster_locked.go b/cmd/cluster_locked.go new file mode 100644 index 00000000..6ce18f4a --- /dev/null +++ b/cmd/cluster_locked.go @@ -0,0 +1,63 @@ +package cmd + +import ( + "context" + "fmt" + "github.com/qovery/qovery-cli/utils" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "io" + "net/http" + "os" + "strconv" + "text/tabwriter" + "time" +) + +var clusterLockedCmd = &cobra.Command{ + Use: "locked", + Short: "List locked clusters", + Run: func(cmd *cobra.Command, args []string) { + clusterLocked() + }, +} + +func init() { + clusterLockedCmd.Flags().StringVarP(&organizationId, "organization-id", "o", "", "Organization ID") + clusterLockCmd.MarkFlagRequired("organization-id") + + clusterCmd.AddCommand(clusterLockedCmd) +} + +func clusterLocked() { + tokenType, token, err := utils.GetAccessToken() + if err != nil { + utils.PrintlnError(err) + os.Exit(1) + } + + client := utils.GetQoveryClient(tokenType, token) + lockedClusters, res, err := client.OrganizationClusterLockAPI.ListClusterLock(context.Background(), organizationId).Execute() + if res != nil && res.StatusCode != http.StatusOK { + result, _ := io.ReadAll(res.Body) + log.Errorf("Could not list locked clusters : %s. %s", res.Status, string(result)) + return + } + + if err != nil { + log.Fatal(err) + } + + w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + format := "%s\t | %s\t | %s\t | %s\t | %s\t | %s\n" + fmt.Fprintf(w, format, "", "cluster_id", "locked_at", "ttl_in_days", "locked_by", "reason") + for idx, lock := range lockedClusters.Results { + ttlInDays := "infinite" + if lock.TtlInDays != nil { + ttlInDays = strconv.Itoa(int(*lock.TtlInDays)) + } + + fmt.Fprintf(w, format, fmt.Sprintf("%d", idx+1), lock.ClusterId, lock.LockedAt.Format(time.RFC1123), ttlInDays, lock.OwnerName, lock.Reason) + } + w.Flush() +} diff --git a/cmd/cluster_unlock.go b/cmd/cluster_unlock.go new file mode 100644 index 00000000..edec17a6 --- /dev/null +++ b/cmd/cluster_unlock.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "context" + "fmt" + "github.com/qovery/qovery-cli/utils" + "github.com/spf13/cobra" + "os" +) + +var clusterUnlockCmd = &cobra.Command{ + Use: "unlock", + Short: "Unlock a cluster", + Run: func(cmd *cobra.Command, args []string) { + unlockCluster() + }, +} + +func init() { + clusterUnlockCmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Cluster ID") + clusterLockCmd.MarkFlagRequired("cluster-id") + + clusterCmd.AddCommand(clusterUnlockCmd) +} + +func unlockCluster() { + if utils.Validate("unlock") { + tokenType, token, err := utils.GetAccessToken() + if err != nil { + utils.PrintlnError(err) + os.Exit(1) + } + + client := utils.GetQoveryClient(tokenType, token) + + _, err = client.ClustersAPI.UnlockCluster(context.Background(), clusterId).Execute() + if err != nil { + utils.PrintlnError(err) + os.Exit(1) + } else { + fmt.Println("Cluster unlocked.") + } + } +} diff --git a/go.mod b/go.mod index df0963f9..f819eb8c 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/posthog/posthog-go v1.2.24 github.com/pterm/pterm v0.12.79 - github.com/qovery/qovery-client-go v0.0.0-20241203095515-b7bfff7f6c11 + github.com/qovery/qovery-client-go v0.0.0-20241227140826-136a47d7533e github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index d36eafeb..06b351de 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,14 @@ github.com/qovery/qovery-client-go v0.0.0-20240918181134-faa9e7a86f41 h1:O31SMjm github.com/qovery/qovery-client-go v0.0.0-20240918181134-faa9e7a86f41/go.mod h1:9eHj5a4EtXGIyfbvVL3HVYW9k7Xmiwi00OqHrP4dc10= github.com/qovery/qovery-client-go v0.0.0-20241203095515-b7bfff7f6c11 h1:racjGI7jQTgKOZTrYFGwCtceW3aMhfCKQZdpjVENZqM= github.com/qovery/qovery-client-go v0.0.0-20241203095515-b7bfff7f6c11/go.mod h1:hAMMDu1kk2rNJRf8MiYV0E+07DhDXpvNddj9q8YpbFs= +github.com/qovery/qovery-client-go v0.0.0-20241226152139-3a0a7f99a7d5 h1:CUMeRESypO2DZOC4FsO3z69QksM6p1njgoNxr4h9Uto= +github.com/qovery/qovery-client-go v0.0.0-20241226152139-3a0a7f99a7d5/go.mod h1:hAMMDu1kk2rNJRf8MiYV0E+07DhDXpvNddj9q8YpbFs= +github.com/qovery/qovery-client-go v0.0.0-20241227121330-2fc6e5c1306e h1:o4ANe0EYT6vyRyNgz3rnNKUTSoJmPdPlvWe4wiJeT7s= +github.com/qovery/qovery-client-go v0.0.0-20241227121330-2fc6e5c1306e/go.mod h1:hAMMDu1kk2rNJRf8MiYV0E+07DhDXpvNddj9q8YpbFs= +github.com/qovery/qovery-client-go v0.0.0-20241227132052-aa8926d349d7 h1:qBKc/1pdXeFJi5ZsMlxR0QUNFb64uSIQhBjFIj7VOhA= +github.com/qovery/qovery-client-go v0.0.0-20241227132052-aa8926d349d7/go.mod h1:hAMMDu1kk2rNJRf8MiYV0E+07DhDXpvNddj9q8YpbFs= +github.com/qovery/qovery-client-go v0.0.0-20241227140826-136a47d7533e h1:w9D5Z6b/8XpIPwICCbAqctOkFRIMZdI5tNJ6pWOHgYM= +github.com/qovery/qovery-client-go v0.0.0-20241227140826-136a47d7533e/go.mod h1:hAMMDu1kk2rNJRf8MiYV0E+07DhDXpvNddj9q8YpbFs= 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= diff --git a/pkg/lock.go b/pkg/lock.go index 778eff59..8e926b83 100644 --- a/pkg/lock.go +++ b/pkg/lock.go @@ -1,7 +1,6 @@ package pkg import ( - "bytes" "encoding/json" "fmt" "io" @@ -52,41 +51,6 @@ func LockedClusters() { w.Flush() } -func LockById(clusterId string, reason string) { - utils.GetAdminUrl() - - if reason == "" { - log.Errorf("Lock reason is required") - return - } - - if utils.Validate("lock") { - res := updateLockById(clusterId, reason, http.MethodPost) - - if res.StatusCode != http.StatusOK { - result, _ := io.ReadAll(res.Body) - log.Errorf("Could not lock cluster : %s. %s", res.Status, string(result)) - } else { - fmt.Println("Cluster locked.") - } - } -} - -func UnockById(clusterId string) { - utils.GetAdminUrl() - - if utils.Validate("unlock") { - res := updateLockById(clusterId, "", http.MethodDelete) - - if res.StatusCode != http.StatusOK { - result, _ := io.ReadAll(res.Body) - log.Errorf("Could not unlock cluster : %s. %s", res.Status, string(result)) - } else { - fmt.Println("Cluster unlocked.") - } - } -} - func listLockedClusters() *http.Response { tokenType, token, err := utils.GetAccessToken() if err != nil { @@ -108,34 +72,3 @@ func listLockedClusters() *http.Response { } return res } - -func updateLockById(clusterId string, reason string, method string) *http.Response { - tokenType, token, err := utils.GetAccessToken() - if err != nil { - utils.PrintlnError(err) - os.Exit(0) - } - - payload := map[string]string{} - if method == http.MethodPost { - payload["reason"] = reason - } - body, err := json.Marshal(payload) - if err != nil { - log.Fatal(err) - } - - url := fmt.Sprintf("%s/cluster/lock/%s", utils.GetAdminUrl(), clusterId) - req, err := http.NewRequest(method, url, bytes.NewBuffer(body)) - if err != nil { - log.Fatal(err) - } - req.Header.Set("Authorization", utils.GetAuthorizationHeaderValue(tokenType, token)) - req.Header.Set("Content-Type", "application/json") - - res, err := http.DefaultClient.Do(req) - if err != nil { - log.Fatal(err) - } - return res -}