Skip to content

Commit

Permalink
support update and switchover DR
Browse files Browse the repository at this point in the history
  • Loading branch information
posriniv committed Oct 22, 2024
1 parent fac1338 commit 7f04579
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 0 deletions.
91 changes: 91 additions & 0 deletions cmd/cluster/dr/switchover_dr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Licensed to Yugabyte, Inc. under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership. Yugabyte
// licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package dr

import (
"fmt"
"os"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
ybmAuthClient "github.com/yugabyte/ybm-cli/internal/client"
"github.com/yugabyte/ybm-cli/internal/formatter"
ybmclient "github.com/yugabyte/yugabytedb-managed-go-client-internal"
)

var switchoverDrCmd = &cobra.Command{
Use: "switchover",
Short: "Switchover DR for a cluster",
Long: `Switchover DR for a cluster`,
Run: func(cmd *cobra.Command, args []string) {
authApi, err := ybmAuthClient.NewAuthApiClient()
if err != nil {
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}
authApi.GetInfo("", "")

drName, _ := cmd.Flags().GetString("dr-name")
clusterId, err := authApi.GetClusterIdByName(ClusterName)
if err != nil {
logrus.Fatalf("Could not get cluster data: %s", ybmAuthClient.GetApiErrorDetails(err))
}
drId, err := authApi.GetDrIdByName(clusterId, drName)
if err != nil {
logrus.Fatal(err)
}

response, err := authApi.SwitchoverXClusterDr(clusterId, drId).Execute()
if err != nil {
logrus.Debugf("Full HTTP response: %v", response)
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}

msg := fmt.Sprintf("Switchover is going on for the DR %s ", formatter.Colorize(drName, formatter.GREEN_COLOR))

if viper.GetBool("wait") {
returnStatus, err := authApi.WaitForTaskCompletion(clusterId, ybmclient.ENTITYTYPEENUM_CLUSTER, ybmclient.TASKTYPEENUM_DR_SWITCHOVER, []string{"FAILED", "SUCCEEDED"}, msg)
if err != nil {
logrus.Fatalf("error when getting task status: %s", err)
}
if returnStatus != "SUCCEEDED" {
logrus.Fatalf("Operation failed with error: %s", returnStatus)
}
fmt.Printf("The DR %s has been created\n", formatter.Colorize(drName, formatter.GREEN_COLOR))

drGetResp, r, err := authApi.GetXClusterDr(clusterId, drId).Execute()
if err != nil {
logrus.Debugf("Full HTTP response: %v", r)
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}
drCtx := formatter.Context{
Output: os.Stdout,
Format: formatter.NewDrFormat(viper.GetString("output")),
}

formatter.DrWrite(drCtx, []ybmclient.XClusterDrData{drGetResp.GetData()}, *authApi)
} else {
fmt.Println(msg)
}

},
}

func init() {
DrCmd.AddCommand(switchoverDrCmd)
switchoverDrCmd.Flags().String("dr-name", "", "[REQUIRED] Name of the DR configuration.")
switchoverDrCmd.MarkFlagRequired("dr-name")
}
113 changes: 113 additions & 0 deletions cmd/cluster/dr/update_dr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Licensed to Yugabyte, Inc. under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership. Yugabyte
// licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package dr

import (
"fmt"
"os"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
ybmAuthClient "github.com/yugabyte/ybm-cli/internal/client"
"github.com/yugabyte/ybm-cli/internal/formatter"
ybmclient "github.com/yugabyte/yugabytedb-managed-go-client-internal"
)

var updateDrCmd = &cobra.Command{
Use: "update",
Short: "Update DR for a cluster",
Long: `Update DR for a cluster`,
Run: func(cmd *cobra.Command, args []string) {
authApi, err := ybmAuthClient.NewAuthApiClient()
if err != nil {
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}
authApi.GetInfo("", "")

drName, _ := cmd.Flags().GetString("dr-name")
databases, _ := cmd.Flags().GetStringArray("databases")
clusterId, err := authApi.GetClusterIdByName(ClusterName)
if err != nil {
logrus.Fatalf("Could not get cluster data: %s", ybmAuthClient.GetApiErrorDetails(err))
}
drId, err := authApi.GetDrIdByName(clusterId, drName)
if err != nil {
logrus.Fatal(err)
}
namespacesResp, r, err := authApi.GetClusterNamespaces(clusterId).Execute()
if err != nil {
logrus.Debugf("Full HTTP response: %v", r)
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}
dbNameToIdMap := map[string]string{}
for _, namespace := range namespacesResp.Data {
dbNameToIdMap[namespace.GetName()] = namespace.GetId()
}
databaseIds := []string{}
for _, database := range databases {
if databaseId, exists := dbNameToIdMap[database]; exists {
databaseIds = append(databaseIds, databaseId)
} else {
logrus.Fatalf("The database %s doesn't exist", database)
}
}
updateDrRequest := ybmclient.NewEditXClusterDrRequest(*ybmclient.NewEditXClusterDrSpec(databaseIds))
drResp, response, err := authApi.EditXClusterDr(clusterId, drId).EditXClusterDrRequest(*updateDrRequest).Execute()
if err != nil {
logrus.Debugf("Full HTTP response: %v", response)
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}

msg := fmt.Sprintf("The DR %s is being created", formatter.Colorize(drName, formatter.GREEN_COLOR))

if viper.GetBool("wait") {
returnStatus, err := authApi.WaitForTaskCompletion(clusterId, ybmclient.ENTITYTYPEENUM_CLUSTER, ybmclient.TASKTYPEENUM_EDIT_DR, []string{"FAILED", "SUCCEEDED"}, msg)
if err != nil {
logrus.Fatalf("error when getting task status: %s", err)
}
if returnStatus != "SUCCEEDED" {
logrus.Fatalf("Operation failed with error: %s", returnStatus)
}
fmt.Printf("The DR %s has been created\n", formatter.Colorize(drName, formatter.GREEN_COLOR))

drGetResp, r, err := authApi.GetXClusterDr(clusterId, drId).Execute()
if err != nil {
logrus.Debugf("Full HTTP response: %v", r)
logrus.Fatalf(ybmAuthClient.GetApiErrorDetails(err))
}
drResp = drGetResp
} else {
fmt.Println(msg)
}

drCtx := formatter.Context{
Output: os.Stdout,
Format: formatter.NewDrFormat(viper.GetString("output")),
}

formatter.DrWrite(drCtx, []ybmclient.XClusterDrData{drResp.GetData()}, *authApi)

},
}

func init() {
DrCmd.AddCommand(updateDrCmd)
updateDrCmd.Flags().String("dr-name", "", "[REQUIRED] Name of the DR configuration.")
updateDrCmd.MarkFlagRequired("dr-name")
updateDrCmd.Flags().StringArray("databases", []string{}, "[REQUIRED] Databases to be replicated.")
updateDrCmd.MarkFlagRequired("databases")
}
8 changes: 8 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,14 @@ func (a *AuthApiClient) CreateXClusterDr(clusterId string) ybmclient.ApiCreateXC
return a.ApiClient.XclusterDrApi.CreateXClusterDr(a.ctx, a.AccountID, a.ProjectID, clusterId)
}

func (a *AuthApiClient) EditXClusterDr(clusterId string, drId string) ybmclient.ApiEditXClusterDrRequest {
return a.ApiClient.XclusterDrApi.EditXClusterDr(a.ctx, a.AccountID, a.ProjectID, clusterId, drId)
}

func (a *AuthApiClient) SwitchoverXClusterDr(clusterId string, drId string) ybmclient.ApiSwitchoverRequest {
return a.ApiClient.XclusterDrApi.Switchover(a.ctx, a.AccountID, a.ProjectID, clusterId, drId)
}

func (a *AuthApiClient) GetXClusterDr(clusterId string, drId string) ybmclient.ApiGetXClusterDrRequest {
return a.ApiClient.XclusterDrApi.GetXClusterDr(a.ctx, a.AccountID, a.ProjectID, clusterId, drId)
}
Expand Down

0 comments on commit 7f04579

Please sign in to comment.