Skip to content

Commit

Permalink
Database: Support user access control for Redis databases (#383)
Browse files Browse the repository at this point in the history
* Support user access control for Redis Managed Databases

* Make at least one Redis access control flag required
  • Loading branch information
christhemorse authored Dec 5, 2023
1 parent 673ca75 commit 84f650c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
61 changes: 61 additions & 0 deletions cmd/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ func Database() *cobra.Command { //nolint:funlen
databaseUserCreate.Flags().StringP("encryption", "e", "", "encryption type for the new managed database user (MySQL only)")
databaseUserUpdate.Flags().StringP("password", "p", "",
"new password for the manaaged database user (leave empty to generate a random secure password)")
userACLCmd := &cobra.Command{
Use: "acl",
Short: "commands to handle managed database user access control (Redis only)",
Long: ``,
}
userACLCmd.AddCommand(databaseUserUpdateACL)
databaseUserUpdateACL.Flags().StringSliceP("redis-acl-categories", "", []string{},
"list of rules for command categories")
databaseUserUpdateACL.Flags().StringSliceP("redis-acl-channels", "", []string{},
"list of publish/subscribe channel patterns")
databaseUserUpdateACL.Flags().StringSliceP("redis-acl-commands", "", []string{},
"list of rules for individual commands")
databaseUserUpdateACL.Flags().StringSliceP("redis-acl-keys", "", []string{},
"list of key access rules")
databaseUserUpdateACL.MarkFlagsOneRequired("redis-acl-categories", "redis-acl-channels", "redis-acl-commands", "redis-acl-keys")
userCmd.AddCommand(userACLCmd)
databaseCmd.AddCommand(userCmd)

// Database logical db flags
Expand Down Expand Up @@ -724,6 +740,51 @@ var databaseUserDelete = &cobra.Command{
},
}

var databaseUserUpdateACL = &cobra.Command{
Use: "update <databaseID> <username>",
Short: "Update a user's access control configuration within a Redis managed database",
Long: "",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return errors.New("please provide a databaseID and username")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
redisACLCategories, _ := cmd.Flags().GetStringSlice("redis-acl-categories")
redisACLCategoriesSet := cmd.Flags().Lookup("redis-acl-categories").Changed
redisACLChannels, _ := cmd.Flags().GetStringSlice("redis-acl-channels")
redisACLChannelsSet := cmd.Flags().Lookup("redis-acl-channels").Changed
redisACLCommands, _ := cmd.Flags().GetStringSlice("redis-acl-commands")
redisACLCommandsSet := cmd.Flags().Lookup("redis-acl-commands").Changed
redisACLKeys, _ := cmd.Flags().GetStringSlice("redis-acl-keys")
redisACLKeysSet := cmd.Flags().Lookup("redis-acl-keys").Changed

var opt = &govultr.DatabaseUserACLReq{}
if redisACLCategoriesSet {
opt.RedisACLCategories = &redisACLCategories
}
if redisACLChannelsSet {
opt.RedisACLChannels = &redisACLChannels
}
if redisACLCommandsSet {
opt.RedisACLCommands = &redisACLCommands
}
if redisACLKeysSet {
opt.RedisACLKeys = &redisACLKeys
}

// Make the request
databaseUser, _, err := client.Database.UpdateUserACL(context.TODO(), args[0], args[1], opt)
if err != nil {
fmt.Printf("error updating managed database user access control : %v\n", err)
os.Exit(1)
}

printer.DatabaseUser(*databaseUser)
},
}

var databaseDBList = &cobra.Command{
Use: "list <databaseID>",
Short: "list all logical databases within a managed database",
Expand Down
14 changes: 14 additions & 0 deletions cmd/printer/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,13 @@ func DatabaseUserList(databaseUsers []govultr.DatabaseUser, meta *govultr.Meta)
if databaseUsers[u].Encryption != "" {
display(columns{"ENCRYPTION", databaseUsers[u].Encryption})
}
if databaseUsers[u].AccessControl != nil {
display(columns{"ACCESS CONTROL"})
display(columns{"REDIS ACL CATEGORIES", databaseUsers[u].AccessControl.RedisACLCategories})
display(columns{"REDIS ACL CHANNELS", databaseUsers[u].AccessControl.RedisACLChannels})
display(columns{"REDIS ACL COMMANDS", databaseUsers[u].AccessControl.RedisACLCommands})
display(columns{"REDIS ACL KEYS", databaseUsers[u].AccessControl.RedisACLKeys})
}
display(columns{"---------------------------"})
}

Expand All @@ -462,6 +469,13 @@ func DatabaseUser(databaseUser govultr.DatabaseUser) {
if databaseUser.Encryption != "" {
display(columns{"ENCRYPTION", databaseUser.Encryption})
}
if databaseUser.AccessControl != nil {
display(columns{"ACCESS CONTROL"})
display(columns{"REDIS ACL CATEGORIES", databaseUser.AccessControl.RedisACLCategories})
display(columns{"REDIS ACL CHANNELS", databaseUser.AccessControl.RedisACLChannels})
display(columns{"REDIS ACL COMMANDS", databaseUser.AccessControl.RedisACLCommands})
display(columns{"REDIS ACL KEYS", databaseUser.AccessControl.RedisACLKeys})
}
}

// DatabaseDBList will generate a printer display of logical databases within a Managed Database cluster
Expand Down

0 comments on commit 84f650c

Please sign in to comment.