Skip to content

Commit

Permalink
DBAAS: support for user operations (#654)
Browse files Browse the repository at this point in the history
# Description
<!--
* Prefix: the title with the component name being changed. Add a short
and self describing sentence to ease the review
* Please add a few lines providing context and describing the change
* Please self comment changes whenever applicable to help with the
review process
* Please keep the checklist as part of the PR. Tick what applies to this
change.
-->

This adds for the following API calls:

- Creating users for supported DBAAS services
- Deleting users for supported DBAAS services
- Resetting user credentials for supported DBAAS services
- Listing and showing user details for supported DBAAS services


## Checklist
(For exoscale contributors)

* [ ] Changelog updated (under *Unreleased* block)
* [x] Testing

## Testing

```





➜  ~/exo/cli git:(tgrondier/sc-104242/cli-users) ✗ go run . dbaas user delete test myuser3                                                                                                                                  24-11-29 16:12 
[+] Are you sure you want to delete user "myuser3" [yN]: y
 ✔ Creating DBaaS user "myuser3" 0s
┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼
│   DATABASE SERVICE    │                                                                                                                              │
┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼
│ Zone                  │ ch-gva-2                                                                                                                     │
│ Name                  │ test                                                                                                                         │
│ Type                  │ mysql                                                                                                                        │
│ Plan                  │ hobbyist-2                                                                                                                   │
│ Disk Size             │ 8.0 GiB                                                                                                                      │
│ State                 │ running                                                                                                                      │
│ Creation Date         │ 2024-11-29 15:00:34 +0000 UTC                                                                                                │
│ Update Date           │ 2024-11-29 15:02:56 +0000 UTC                                                                                                │
│ Nodes                 │ 1                                                                                                                            │
│ Node CPUs             │ 2                                                                                                                            │
│ Node Memory           │ 2.0 GiB                                                                                                                      │
│ Termination Protected │ false                                                                                                                        │
│ Maintenance           │ saturday (19:26:58)                                                                                                          │
...
│ Users                 │ avnadmin (primary)                                                                                                           │

┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼



➜  ~/exo/cli git:(tgrondier/sc-104242/cli-users) ✗ go run . dbaas user reset-credentials test myuser2                                                                                                                                                                                                       24-12-02 10:52 
 ✔ Resetting DBaaS user "myuser2" 0s
┼────────────────┼──────────────────────────┼
│  SERVICE USER  │                          │
┼────────────────┼──────────────────────────┼
│ Username       │ myuser2                  │
│ Type           │ regular                  │
│ Password       │ AVNS_46o-1gO9pE8acEc9Nzp │
│ Access Control │   Categories             │
│                │   Channels     *         │
│                │   Commands               │
│                │   Keys                   │
│                │                          │
┼────────────────┼──────────────────────────┼


➜  ~/exo/cli git:(tgrondier/sc-104242/cli-users) ✗ go run . dbaas user create test myuser2                                                                                                                                                                                                                  24-12-02 10:46 
 ✔ Creating DBaaS user "myuser2" 0s
┼────────────────┼──────────────────────────┼
│  SERVICE USER  │                          │
┼────────────────┼──────────────────────────┼
│ Username       │ myuser2                  │
│ Type           │ normal                   │
│ Password       │ AVNS_QWLuqR0A_FCAll3JiVN │
│ Authentication │ caching_sha2_password    │
┼────────────────┼──────────────────────────┼

```
  • Loading branch information
tgrondier authored Dec 9, 2024
1 parent cc0f332 commit 4e00cc6
Show file tree
Hide file tree
Showing 37 changed files with 1,737 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
## Unreleased
### Bug fixes
- config: fixing bug sosEndpoint lost after user switch account #652
- dbaas: added commands for managing service users #654

## 1.81.0

Expand Down
22 changes: 22 additions & 0 deletions cmd/dbaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"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 +177,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(zone))
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(),
}))
}
48 changes: 48 additions & 0 deletions cmd/dbaas_user_create_kafka.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cmd

import (
"fmt"

"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(c.Zone))
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

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

import (
"fmt"

"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(c.Zone))
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
}
45 changes: 45 additions & 0 deletions cmd/dbaas_user_create_opensearch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package cmd

import (
"fmt"

"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(c.Zone))
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
}
45 changes: 45 additions & 0 deletions cmd/dbaas_user_create_pg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package cmd

import (
"fmt"

"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(c.Zone))
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

0 comments on commit 4e00cc6

Please sign in to comment.