From c4adda82bd5867f4924ceefd6eeda5ea5d941f01 Mon Sep 17 00:00:00 2001 From: Fabien FLEUREAU Date: Thu, 7 Nov 2024 11:50:26 +0100 Subject: [PATCH] feat(COR-1082): add admin command to notify admins of failed clusters --- cmd/admin_notify_users_cluster_failure.go | 40 ++++++++++++++++ pkg/admin_notify_users_cluster_failure.go | 56 +++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 cmd/admin_notify_users_cluster_failure.go create mode 100644 pkg/admin_notify_users_cluster_failure.go diff --git a/cmd/admin_notify_users_cluster_failure.go b/cmd/admin_notify_users_cluster_failure.go new file mode 100644 index 0000000..0eaed6e --- /dev/null +++ b/cmd/admin_notify_users_cluster_failure.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" + + "github.com/qovery/qovery-cli/pkg" + "github.com/qovery/qovery-cli/utils" +) + +var ( + adminNotifyUsersClusterFailureCmd = &cobra.Command{ + Use: "notify-users-cluster-failure", + Short: "Notify users of a cluster failure", + Long: `Notify users by email of a cluster having FAILED status. +- (Default) With --cluster-id, only admins of the cluster with the given id will be notified. +- Without --cluster-id, admins of all clusters with FAILED status will be notified. +`, + Run: func(cmd *cobra.Command, args []string) { + notifyUsersClusterFailure() + }, + } +) + +func init() { + adminNotifyUsersClusterFailureCmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Cluster ID") + adminCmd.AddCommand(adminNotifyUsersClusterFailureCmd) +} + +func notifyUsersClusterFailure() { + utils.CheckAdminUrl() + + err := pkg.NotifyUsersClusterFailure(&clusterId) + if err != nil { + utils.PrintlnError(err) + os.Exit(1) + panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011 + } +} diff --git a/pkg/admin_notify_users_cluster_failure.go b/pkg/admin_notify_users_cluster_failure.go new file mode 100644 index 0000000..ecec7ad --- /dev/null +++ b/pkg/admin_notify_users_cluster_failure.go @@ -0,0 +1,56 @@ +package pkg + +import ( + "bytes" + "fmt" + "io" + "net/http" + "os" + "strings" + + "github.com/qovery/qovery-cli/utils" +) + +func NotifyUsersClusterFailure(clusterId *string) error { + var body string + if clusterId != nil { + body = fmt.Sprintf(`{"cluster_ids": ["%s"]}`, *clusterId) + } else { + body = `{"all_failing_clusters": true}` + } + + notifiedClustersResponse, err := postWithBody(utils.AdminUrl+"/cluster/notifyFailedClustersAdmins", body) + if err != nil { + return err + } + result, _ := io.ReadAll(notifiedClustersResponse.Body) + if !strings.Contains(notifiedClustersResponse.Status, "200") { + return fmt.Errorf("could not notify (error %s: %s)", notifiedClustersResponse.Status, string(result)) + } + + utils.Println(fmt.Sprintf("Notification sent for admins of these clusters %s", string(result))) + if err != nil { + return err + } + return nil +} + +func postWithBody(url string, bodyAsString string) (*http.Response, error) { + tokenType, token, err := utils.GetAccessToken() + if err != nil { + utils.PrintlnError(err) + os.Exit(0) + } + + body := bytes.NewBuffer([]byte(bodyAsString)) + + req, err := http.NewRequest(http.MethodPost, url, body) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", utils.GetAuthorizationHeaderValue(tokenType, token)) + req.Header.Set("Content-Type", "application/json") + + return http.DefaultClient.Do(req) +}