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

DBAAS: support for user operations #654

Merged
merged 15 commits into from
Dec 9, 2024
23 changes: 23 additions & 0 deletions cmd/dbaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"github.com/spf13/cobra"
"github.com/xeipuuv/gojsonschema"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/table"
v3 "github.com/exoscale/egoscale/v3"
)

var dbServiceMaintenanceDOWs = []string{
Expand Down Expand Up @@ -176,3 +178,24 @@ func dbaasGetType(ctx context.Context, name, zone string) (string, error) {

return "", fmt.Errorf("%q Database Service not found in zone %q", name, zone)
}

func dbaasGetV3(ctx context.Context, name, zone string) (v3.DBAASServiceCommon, error) {

client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(account.CurrentAccount.DefaultZone))
if err != nil {
return v3.DBAASServiceCommon{}, err
}

dbs, err := client.ListDBAASServices(ctx)
if err != nil {
return v3.DBAASServiceCommon{}, err
}

for _, db := range dbs.DBAASServices {
if string(db.Name) == name {
return db, nil
}
}

return v3.DBAASServiceCommon{}, fmt.Errorf("%q Database Service not found in zone %q", name, zone)
}
14 changes: 14 additions & 0 deletions cmd/dbaas_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cmd

import (
"github.com/spf13/cobra"
)

var dbaasUserCmd = &cobra.Command{
Use: "user",
Short: "Manage DBaaS users",
}

func init() {
dbaasCmd.AddCommand(dbaasUserCmd)
}
79 changes: 79 additions & 0 deletions cmd/dbaas_user_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

type dbaasUserCreateCmd struct {
cliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"create"`

Name string `cli-arg:"#"`
Username string `cli-arg:"#"`

HelpMysql bool `cli-usage:"show usage for flags specific to the mysql type"`
HelpPg bool `cli-usage:"show usage for flags specific to the pg type"`
Zone string `cli-short:"z" cli-usage:"Database Service zone"`

// "mysql" type specific flags
MysqlAuthenticationMethod string `cli-flag:"mysql-authentication-method" cli-usage:"authentication method to be used (\"caching_sha2_password\" or \"mysql_native_password\")." cli-hidden:""`

// "kafka" type specific flags
PostgresAllowReplication bool `cli-flag:"pg-allow-replication" cli-usage:"" cli-hidden:""`
}

func (c *dbaasUserCreateCmd) cmdAliases() []string { return nil }

func (c *dbaasUserCreateCmd) cmdShort() string { return "Create DBAAS user" }

func (c *dbaasUserCreateCmd) cmdLong() string {
return `This command creates a DBAAS user for the specified service.`
}

func (c *dbaasUserCreateCmd) cmdPreRun(cmd *cobra.Command, args []string) error {
switch {

case cmd.Flags().Changed("help-mysql"):
cmdShowHelpFlags(cmd.Flags(), "mysql-")
os.Exit(0)
case cmd.Flags().Changed("help-pg"):
cmdShowHelpFlags(cmd.Flags(), "pg-")
os.Exit(0)
}

cmdSetZoneFlagFromDefault(cmd)
return cliCommandDefaultPreRun(c, cmd, args)
}

func (c *dbaasUserCreateCmd) cmdRun(cmd *cobra.Command, args []string) error {

ctx := gContext
db, err := dbaasGetV3(ctx, c.Name, c.Zone)
if err != nil {
return err
}

switch db.Type {
case "mysql":
return c.createMysql(cmd, args)
case "kafka":
return c.createKafka(cmd, args)
case "pg":
return c.createPg(cmd, args)
case "opensearch":
return c.createOpensearch(cmd, args)
default:
return fmt.Errorf("creating user unsupported for service of type %q", db.Type)
}

}

func init() {
cobra.CheckErr(registerCLICommand(dbaasUserCmd, &dbaasUserCreateCmd{
cliCommandSettings: defaultCLICmdSettings(),
}))
}
49 changes: 49 additions & 0 deletions cmd/dbaas_user_create_kafka.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cmd

import (
"fmt"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

func (c *dbaasUserCreateCmd) createKafka(cmd *cobra.Command, _ []string) error {

ctx := gContext

client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(account.CurrentAccount.DefaultZone))
if err != nil {
return err
}

req := v3.CreateDBAASKafkaUserRequest{Username: v3.DBAASUserUsername(c.Username)}

op, err := client.CreateDBAASKafkaUser(ctx, c.Name, req)

if err != nil {
return err
}

decorateAsyncOperation(fmt.Sprintf("Creating DBaaS user %q", c.Username), func() {
op, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})

if err != nil {
return err
}

if !globalstate.Quiet {

return c.outputFunc((&dbaasUserShowCmd{
Name: c.Name,
Zone: c.Zone,
Username: c.Username,
}).showKafka(ctx))

}

return nil

}
49 changes: 49 additions & 0 deletions cmd/dbaas_user_create_mysql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cmd

import (
"fmt"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

func (c *dbaasUserCreateCmd) createMysql(cmd *cobra.Command, _ []string) error {

ctx := gContext

client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(account.CurrentAccount.DefaultZone))
if err != nil {
return err
}

req := v3.CreateDBAASMysqlUserRequest{Username: v3.DBAASUserUsername(c.Username)}
if c.MysqlAuthenticationMethod != "" {
req.Authentication = v3.EnumMysqlAuthenticationPlugin(c.MysqlAuthenticationMethod)
}

op, err := client.CreateDBAASMysqlUser(ctx, c.Name, req)

if err != nil {
return err
}

decorateAsyncOperation(fmt.Sprintf("Creating DBaaS user %q", c.Username), func() {
op, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})

if err != nil {
return err
}

if !globalstate.Quiet {
return c.outputFunc((&dbaasUserShowCmd{
Name: c.Name,
Zone: c.Zone,
Username: c.Username,
}).showMysql(ctx))
}

return nil
}
46 changes: 46 additions & 0 deletions cmd/dbaas_user_create_opensearch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cmd

import (
"fmt"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

func (c *dbaasUserCreateCmd) createOpensearch(cmd *cobra.Command, _ []string) error {

ctx := gContext

client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(account.CurrentAccount.DefaultZone))
if err != nil {
return err
}

req := v3.CreateDBAASOpensearchUserRequest{Username: v3.DBAASUserUsername(c.Username)}

op, err := client.CreateDBAASOpensearchUser(ctx, c.Name, req)

if err != nil {
return err
}

decorateAsyncOperation(fmt.Sprintf("Creating DBaaS user %q", c.Username), func() {
op, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})

if err != nil {
return err
}

if !globalstate.Quiet {
return c.outputFunc((&dbaasUserShowCmd{
Name: c.Name,
Zone: c.Zone,
Username: c.Username,
}).showOpensearch(ctx))
}

return nil
}
46 changes: 46 additions & 0 deletions cmd/dbaas_user_create_pg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cmd

import (
"fmt"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

func (c *dbaasUserCreateCmd) createPg(cmd *cobra.Command, _ []string) error {

ctx := gContext

client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(account.CurrentAccount.DefaultZone))
if err != nil {
return err
}

req := v3.CreateDBAASPostgresUserRequest{Username: v3.DBAASUserUsername(c.Username), AllowReplication: &c.PostgresAllowReplication}

op, err := client.CreateDBAASPostgresUser(ctx, c.Name, req)

if err != nil {
return err
}

decorateAsyncOperation(fmt.Sprintf("Creating DBaaS user %q", c.Username), func() {
op, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})

if err != nil {
return err
}

if !globalstate.Quiet {
return c.outputFunc((&dbaasUserShowCmd{
Name: c.Name,
Zone: c.Zone,
Username: c.Username,
}).showPG(ctx))
}

return nil
}
61 changes: 61 additions & 0 deletions cmd/dbaas_user_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

type dbaasUserDeleteCmd struct {
cliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"delete"`

Name string `cli-arg:"#"`
Username string `cli-arg:"#"`
Zone string `cli-short:"z" cli-usage:"Database Service zone"`

Force bool `cli-short:"f" cli-usage:"don't prompt for confirmation"`
}

func (c *dbaasUserDeleteCmd) cmdAliases() []string { return nil }

func (c *dbaasUserDeleteCmd) cmdShort() string { return "Delete DBAAS user" }

func (c *dbaasUserDeleteCmd) cmdLong() string {
return `This command deletes a DBAAS user for the specified service.`
}

func (c *dbaasUserDeleteCmd) cmdPreRun(cmd *cobra.Command, args []string) error {
cmdSetZoneFlagFromDefault(cmd)
return cliCommandDefaultPreRun(c, cmd, args)
}

func (c *dbaasUserDeleteCmd) cmdRun(cmd *cobra.Command, args []string) error {

ctx := gContext
db, err := dbaasGetV3(ctx, c.Name, c.Zone)
if err != nil {
return err
}

switch db.Type {
case "mysql":
return c.deleteMysql(cmd, args)
case "kafka":
return c.deleteKafka(cmd, args)
case "pg":
return c.deletePg(cmd, args)
case "opensearch":
return c.deleteOpensearch(cmd, args)
default:
return fmt.Errorf("deleting user unsupported for service of type %q", db.Type)
}

}

func init() {
cobra.CheckErr(registerCLICommand(dbaasUserCmd, &dbaasUserDeleteCmd{
cliCommandSettings: defaultCLICmdSettings(),
}))
}
Loading
Loading