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

Using Viper with cobra to simplify some of the feature #20

Merged
merged 3 commits into from
Jan 12, 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
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
# ybm-cli
A CLI implementation for YB Managed.

# Global configuration
This CLI support 3 possibles configurations:
* Passing values as flags
```shell
ybm --apikey AWERDFSSS --host cloud.yugabyte.com get cluster
```
* Using a configuration file called `.ybm-cli.yaml` under your `$HOME` directory.
You can use the command `ybm configure` to help to setup the file

* Using environment variables (all need to start with `YBM_`)
```shell
export YBM_APIKEY=AWERDFSSS
export YBM_HOST=cloud.yugabyte.com
ybm get cluster
```

By default, `https` will be added to the host if no scheme are provided if you want to use `http`
just add it to the host `http://cloud.yugabyte.com`


## Sample Create Commands:

### Cluster
Expand Down
8 changes: 4 additions & 4 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var getBackupCmd = &cobra.Command{
Long: "Get backups in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {

apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
listBackupRequest := apiClient.BackupApi.ListBackups(context.Background(), accountID, projectID)
Expand Down Expand Up @@ -44,7 +44,7 @@ var restoreBackupCmd = &cobra.Command{
Long: "Restore backups in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {

apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down Expand Up @@ -75,7 +75,7 @@ var createBackupCmd = &cobra.Command{
Short: "Create backup in YugabyteDB Managed",
Long: "Create backup in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterName, _ := cmd.Flags().GetString("cluster-name")
Expand Down Expand Up @@ -119,7 +119,7 @@ var deleteBackupCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
backupID, _ := cmd.Flags().GetString("backup-id")

apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down
8 changes: 4 additions & 4 deletions cmd/cdc_sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var getCdcSinkCmd = &cobra.Command{
Short: "Get CDC Sink in YugabyteDB Managed",
Long: `Get CDC Sink in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)

cdcSinkName, _ := cmd.Flags().GetString("name")
Expand All @@ -44,7 +44,7 @@ var createCdcSinkCmd = &cobra.Command{
Short: "Create CDC Sink in YugabyteDB Managed",
Long: `Create CDC Sink in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)

cdcSinkName, _ := cmd.Flags().GetString("name")
Expand Down Expand Up @@ -86,7 +86,7 @@ var editCdcSinkCmd = &cobra.Command{
Short: "Edit CDC Sink in YugabyteDB Managed",
Long: `Edit CDC Sink in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)

cdcSinkName, _ := cmd.Flags().GetString("name")
Expand Down Expand Up @@ -135,7 +135,7 @@ var deleteCdcSinkCmd = &cobra.Command{
Short: "Delete CDC Sink in YugabyteDB Managed",
Long: `Delete CDC Sink in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)

cdcSinkName, _ := cmd.Flags().GetString("name")
Expand Down
32 changes: 18 additions & 14 deletions cmd/cdc_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var getCdcStreamCmd = &cobra.Command{
Short: "Get CDC Stream in YugabyteDB Managed",
Long: `Get CDC Stream in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down Expand Up @@ -48,30 +48,33 @@ var createCdcStreamCmd = &cobra.Command{
Short: "Create CDC Stream in YugabyteDB Managed",
Long: `Create CDC Stream in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterName, _ := cmd.Flags().GetString("cluster")
clusterID, _, _ := getClusterID(context.Background(), apiClient, accountID, projectID, clusterName)

// TODO: handle failures in the above
fmt.Fprintf(os.Stderr, "accountID: %v, projectID: %v, clusterID: %v", accountID, projectID, clusterID)

cdcStreamName, _ := cmd.Flags().GetString("name")
cdcSinkName, _ := cmd.Flags().GetString("sink")
sinkId, _, _ := getCdcSinkID(context.Background(), apiClient, accountID, cdcSinkName)
namespace, _ := cmd.Flags().GetString("namespace")
dbName, _ := cmd.Flags().GetString("db-name")
tables, _ := cmd.Flags().GetStringArray("tables")
snapshotExistingData, _ := cmd.Flags().GetBool("snapshot-existing-data")
kafkaPrefix, _ := cmd.Flags().GetString("kafka-prefix")

cdcStreamSpec := ybmclient.CdcStreamSpec{
Name: cdcStreamName,
CdcSinkId: sinkId,
Namespace: namespace,
DbName: dbName,
Tables: tables,
Name: cdcStreamName,
CdcSinkId: sinkId,
DbName: dbName,
Tables: tables,
SnapshotExistingData: &snapshotExistingData,
KafkaPrefix: &kafkaPrefix,
}

createClusterRequest := ybmclient.NewCreateCdcStreamRequest(cdcStreamSpec, true)

resp, r, err := apiClient.CdcApi.CreateCdcStream(context.Background(), accountID, projectID, clusterID).CreateCdcStreamRequest(*createClusterRequest).Execute()
resp, r, err := apiClient.CdcApi.CreateCdcStream(context.Background(), accountID, projectID, clusterID).CdcStreamSpec(cdcStreamSpec).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `CdcApi.CreateCdcStream``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
Expand All @@ -87,7 +90,7 @@ var editCdcStreamCmd = &cobra.Command{
Short: "Edit CDC Stream in YugabyteDB Managed",
Long: `Edit CDC Stream in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down Expand Up @@ -128,7 +131,7 @@ var deleteCdcStreamCmd = &cobra.Command{
Short: "Delete CDC Stream in YugabyteDB Managed",
Long: `Delete CDC Stream in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down Expand Up @@ -163,8 +166,9 @@ func init() {
createCdcStreamCmd.Flags().String("cluster", "", "Name of the Cluster")
createCdcStreamCmd.Flags().StringArray("tables", []string{}, "Database tables the Cdc Stream will listen to")
createCdcStreamCmd.Flags().String("sink", "", "Destination sink for the CDC Stream")
createCdcStreamCmd.Flags().String("namespace", "", "Namespace that the Cdc Stream will listen to")
createCdcStreamCmd.Flags().String("db-name", "", "Database that the Cdc Stream will listen to")
createCdcStreamCmd.Flags().String("snapshot-existing-data", "", "Whether to snapshot the existing data in the database")
createCdcStreamCmd.Flags().String("kafka-prefix", "", "A prefix for the Kafka topics")

updateCmd.AddCommand(editCdcStreamCmd)
editCdcStreamCmd.Flags().String("name", "", "Name of the CDC Stream")
Expand Down
23 changes: 22 additions & 1 deletion cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// configureCmd represents the configure command
Expand All @@ -18,8 +19,28 @@ var configureCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
fmt.Print("Enter API Key: ")
var apiKey string
var host string
fmt.Scanln(&apiKey)
os.WriteFile("credentials", []byte(apiKey), 0644)
viper.GetViper().Set("apikey", &apiKey)
fmt.Print("Enter Host: ")
fmt.Scanln(&host)
viper.GetViper().Set("host", &host)
err := viper.WriteConfig()
if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Fprintln(os.Stdout, "No config was found a new one will be created.")
//Try to create the file
err = viper.SafeWriteConfig()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when writing new config file: %v\n", err)

}
} else {
fmt.Fprintf(os.Stderr, "Error when writing config file: %v\n", err)
return
}
}
fmt.Println("Configuration file sucessfully updated.")
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var createClusterCmd = &cobra.Command{
Long: "Create a cluster in YB Managed",
Run: func(cmd *cobra.Command, args []string) {

apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down
2 changes: 1 addition & 1 deletion cmd/delete_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var deleteClusterCmd = &cobra.Command{
Short: "Delete cluster in YugabyteDB Managed",
Long: "Delete cluster in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterName, _ := cmd.Flags().GetString("cluster-name")
Expand Down
2 changes: 1 addition & 1 deletion cmd/get_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var getClusterCmd = &cobra.Command{
Short: "Get clusters in YugabyteDB Managed",
Long: "Get clusters in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterListRequest := apiClient.ClusterApi.ListClusters(context.Background(), accountID, projectID)
Expand Down
6 changes: 3 additions & 3 deletions cmd/network_allow_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var getNetworkAllowListCmd = &cobra.Command{
Short: "Get network allow list in YugabyteDB Managed",
Long: `Get network allow list in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down Expand Up @@ -63,7 +63,7 @@ var createNetworkAllowListCmd = &cobra.Command{
Short: "Create network allow lists in YugabyteDB Managed",
Long: `Create network allow lists in YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand All @@ -88,7 +88,7 @@ var deleteNetworkAllowListCmd = &cobra.Command{
Short: "Delete network allow list from YugabyteDB Managed",
Long: `Delete network allow list from YugabyteDB Managed`,
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)

Expand Down
2 changes: 1 addition & 1 deletion cmd/pause_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var pauseClusterCmd = &cobra.Command{
Short: "Pause clusters in YugabyteDB Managed",
Long: "Pause clusters in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterName, _ := cmd.Flags().GetString("cluster-name")
Expand Down
8 changes: 4 additions & 4 deletions cmd/read_replica.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ var getReadReplicaCmd = &cobra.Command{
Short: "Get read replica in YugabyteDB Managed",
Long: "Get read replica in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterID, _, _ := getClusterID(context.Background(), apiClient, accountID, projectID, clusterName)
Expand All @@ -98,7 +98,7 @@ var createReadReplicaCmd = &cobra.Command{
Short: "Create read replica in YugabyteDB Managed",
Long: "Create read replica in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterID, _, _ := getClusterID(context.Background(), apiClient, accountID, projectID, clusterName)
Expand All @@ -120,7 +120,7 @@ var updateReadReplicaCmd = &cobra.Command{
Short: "Edit read replica in YugabyteDB Managed",
Long: "Edit read replica in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterID, _, _ := getClusterID(context.Background(), apiClient, accountID, projectID, clusterName)
Expand All @@ -142,7 +142,7 @@ var deleteReadReplicaCmd = &cobra.Command{
Short: "Delete read replica from YugabyteDB Managed",
Long: "Delete read replica from YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterID, _, _ := getClusterID(context.Background(), apiClient, accountID, projectID, clusterName)
Expand Down
2 changes: 1 addition & 1 deletion cmd/resume_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var resumeClusterCmd = &cobra.Command{
Short: "Pause clusters in YugabyteDB Managed",
Long: "Pause clusters in YugabyteDB Managed",
Run: func(cmd *cobra.Command, args []string) {
apiClient, _ := getApiClient(context.Background())
apiClient, _ := getApiClient(context.Background(), cmd)
accountID, _, _ := getAccountID(context.Background(), apiClient)
projectID, _, _ := getProjectID(context.Background(), apiClient, accountID)
clusterName, _ := cmd.Flags().GetString("cluster-name")
Expand Down
49 changes: 48 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ Copyright © 2022 NAME HERE <EMAIL ADDRESS>
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
cfgFile string
// host string
// apiKey string
)

// rootCmd represents the base command when called without any subcommands
Expand All @@ -29,14 +37,53 @@ func Execute() {
}
}

func setDefaults() {
viper.SetDefault("host", "devcloud.yugabyte.com")

}

func init() {
cobra.OnInitialize(initConfig)
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
setDefaults()
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ybm-cli.yaml)")
rootCmd.PersistentFlags().StringP("host", "", "", "YBM Api hostname")
rootCmd.PersistentFlags().StringP("apiKey", "a", "", "YBM Api Key")

// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ybm-cli.yaml)")
//Bind peristents flags to viper
viper.BindPFlag("host", rootCmd.PersistentFlags().Lookup("host"))
viper.BindPFlag("apiKey", rootCmd.PersistentFlags().Lookup("apiKey"))

// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := os.UserHomeDir()
cobra.CheckErr(err)

// Search config in home directory with name ".ybm-cli" (without extension).
viper.AddConfigPath(home)
viper.SetConfigType("yaml")
viper.SetConfigName(".ybm-cli")
}

//Will check every environment variable starting with YBM_
viper.SetEnvPrefix("ybm")
//Read all enviromnent variable that match YBM_ENVNAME
viper.AutomaticEnv() // read in environment variables that match

// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
}
}
Loading