NET-1227: User Cli cmds Update (#3064)

* generalise smtp config

* copy over smtp vars

* env new line

* fix master key api access

* comment user tests

* fix network and user invite for master key access

* remove email sender type

* user mgmt commands

* check user role on CE

* user role nmtcl cmds

* user groups commands

* fix role and groups command

* fix user create cmd

* add usage info

* rm user role check

* fix user update cmd

* fix static check
This commit is contained in:
Abhishek K 2024-08-25 07:25:40 +05:30 committed by GitHub
parent 1924da2956
commit 5a4d0663da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 356 additions and 20 deletions

View file

@ -1,6 +1,8 @@
package user package user
import ( import (
"strings"
"github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -12,18 +14,41 @@ var userCreateCmd = &cobra.Command{
Short: "Create a new user", Short: "Create a new user",
Long: `Create a new user`, Long: `Create a new user`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
user := &models.User{UserName: username, Password: password, IsAdmin: admin} user := &models.User{UserName: username, Password: password, PlatformRoleID: models.UserRoleID(platformID)}
if len(networkRoles) > 0 {
netRolesMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
for netID, netRoles := range networkRoles {
roleMap := make(map[models.UserRoleID]struct{})
for _, roleID := range strings.Split(netRoles, " ") {
roleMap[models.UserRoleID(roleID)] = struct{}{}
}
netRolesMap[models.NetworkID(netID)] = roleMap
}
user.NetworkRoles = netRolesMap
}
if len(groups) > 0 {
grMap := make(map[models.UserGroupID]struct{})
for _, groupID := range groups {
grMap[models.UserGroupID(groupID)] = struct{}{}
}
user.UserGroups = grMap
}
functions.PrettyPrint(functions.CreateUser(user)) functions.PrettyPrint(functions.CreateUser(user))
}, },
} }
func init() { func init() {
userCreateCmd.Flags().StringVar(&username, "name", "", "Name of the user") userCreateCmd.Flags().StringVar(&username, "name", "", "Name of the user")
userCreateCmd.Flags().StringVar(&password, "password", "", "Password of the user") userCreateCmd.Flags().StringVar(&password, "password", "", "Password of the user")
userCreateCmd.Flags().StringVarP(&platformID, "platform-role", "r", models.ServiceUser.String(),
"Platform Role of the user; run `nmctl roles list` to see available user roles")
userCreateCmd.MarkFlagRequired("name") userCreateCmd.MarkFlagRequired("name")
userCreateCmd.MarkFlagRequired("password") userCreateCmd.MarkFlagRequired("password")
userCreateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ?") userCreateCmd.PersistentFlags().StringToStringVarP(&networkRoles, "network-roles", "n", nil,
userCreateCmd.Flags().StringVar(&networks, "networks", "", "List of networks the user will access to (comma separated)") "Mapping of networkID and list of roles user will be part of (comma separated)")
userCreateCmd.Flags().StringVar(&groups, "groups", "", "List of user groups the user will be part of (comma separated)") userCreateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ? (deprecated v0.25.0 onwards)")
userCreateCmd.Flags().StringArrayVarP(&groups, "groups", "g", nil, "List of user groups the user will be part of (comma separated)")
rootCmd.AddCommand(userCreateCmd) rootCmd.AddCommand(userCreateCmd)
} }

View file

@ -1,9 +1,10 @@
package user package user
var ( var (
username string username string
password string password string
admin bool platformID string
networks string admin bool
groups string networkRoles map[string]string
groups []string
) )

118
cli/cmd/user/groups.go Normal file
View file

@ -0,0 +1,118 @@
package user
import (
"fmt"
"os"
"strings"
"github.com/gravitl/netmaker/cli/cmd/commons"
"github.com/gravitl/netmaker/cli/functions"
"github.com/guumaster/tablewriter"
"github.com/spf13/cobra"
)
var userGroupCmd = &cobra.Command{
Use: "group",
Args: cobra.NoArgs,
Short: "Manage User Groups",
Long: `Manage User Groups`,
}
var userGroupListCmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
Short: "List all user groups",
Long: `List all user groups`,
Run: func(cmd *cobra.Command, args []string) {
data := functions.ListUserGrps()
switch commons.OutputFormat {
case commons.JsonOutput:
functions.PrettyPrint(data)
default:
table := tablewriter.NewWriter(os.Stdout)
h := []string{"ID", "MetaData", "Network Roles"}
table.SetHeader(h)
for _, d := range data {
roleInfoStr := ""
for netID, netRoleMap := range d.NetworkRoles {
roleList := []string{}
for roleID := range netRoleMap {
roleList = append(roleList, roleID.String())
}
roleInfoStr += fmt.Sprintf("[%s]: %s", netID, strings.Join(roleList, ","))
}
e := []string{d.ID.String(), d.MetaData, roleInfoStr}
table.Append(e)
}
table.Render()
}
},
}
var userGroupCreateCmd = &cobra.Command{
Use: "create",
Args: cobra.NoArgs,
Short: "create user group",
Long: `create user group`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("CLI doesn't support creation of groups currently. Visit the dashboard to create one or refer to our api documentation https://docs.v2.netmaker.io/reference")
},
}
var userGroupDeleteCmd = &cobra.Command{
Use: "delete [groupID]",
Args: cobra.ExactArgs(1),
Short: "delete user group",
Long: `delete user group`,
Run: func(cmd *cobra.Command, args []string) {
resp := functions.DeleteUserGrp(args[0])
if resp != nil {
fmt.Println(resp.Message)
}
},
}
var userGroupGetCmd = &cobra.Command{
Use: "get [groupID]",
Args: cobra.ExactArgs(1),
Short: "get user group",
Long: `get user group`,
Run: func(cmd *cobra.Command, args []string) {
data := functions.GetUserGrp(args[0])
switch commons.OutputFormat {
case commons.JsonOutput:
functions.PrettyPrint(data)
default:
table := tablewriter.NewWriter(os.Stdout)
h := []string{"ID", "MetaData", "Network Roles"}
table.SetHeader(h)
roleInfoStr := ""
for netID, netRoleMap := range data.NetworkRoles {
roleList := []string{}
for roleID := range netRoleMap {
roleList = append(roleList, roleID.String())
}
roleInfoStr += fmt.Sprintf("[%s]: %s", netID, strings.Join(roleList, ","))
}
e := []string{data.ID.String(), data.MetaData, roleInfoStr}
table.Append(e)
table.Render()
}
},
}
func init() {
rootCmd.AddCommand(userGroupCmd)
// list roles cmd
userGroupCmd.AddCommand(userGroupListCmd)
// create roles cmd
userGroupCmd.AddCommand(userGroupCreateCmd)
// delete role cmd
userGroupCmd.AddCommand(userGroupDeleteCmd)
// Get Role
userGroupCmd.AddCommand(userGroupGetCmd)
}

View file

@ -2,7 +2,7 @@ package user
import ( import (
"os" "os"
"strconv" "strings"
"github.com/gravitl/netmaker/cli/cmd/commons" "github.com/gravitl/netmaker/cli/cmd/commons"
"github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/cli/functions"
@ -22,9 +22,13 @@ var userListCmd = &cobra.Command{
functions.PrettyPrint(data) functions.PrettyPrint(data)
default: default:
table := tablewriter.NewWriter(os.Stdout) table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "SuperAdmin", "Admin"}) table.SetHeader([]string{"Name", "Platform Role", "Groups"})
for _, d := range *data { for _, d := range *data {
table.Append([]string{d.UserName, strconv.FormatBool(d.IsSuperAdmin), strconv.FormatBool(d.IsAdmin)}) g := []string{}
for gID := range d.UserGroups {
g = append(g, gID.String())
}
table.Append([]string{d.UserName, d.PlatformRoleID.String(), strings.Join(g, ",")})
} }
table.Render() table.Render()
} }

121
cli/cmd/user/roles.go Normal file
View file

@ -0,0 +1,121 @@
package user
import (
"fmt"
"os"
"strconv"
"github.com/gravitl/netmaker/cli/cmd/commons"
"github.com/gravitl/netmaker/cli/functions"
"github.com/guumaster/tablewriter"
"github.com/spf13/cobra"
)
var userRoleCmd = &cobra.Command{
Use: "role",
Args: cobra.NoArgs,
Short: "Manage User Roles",
Long: `Manage User Roles`,
}
// List Roles
var (
platformRoles bool
)
var userRoleListCmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
Short: "List all user roles",
Long: `List all user roles`,
Run: func(cmd *cobra.Command, args []string) {
data := functions.ListUserRoles()
switch commons.OutputFormat {
case commons.JsonOutput:
functions.PrettyPrint(data)
default:
table := tablewriter.NewWriter(os.Stdout)
h := []string{"ID", "Default", "Dashboard Access", "Full Access"}
if !platformRoles {
h = append(h, "Network")
}
table.SetHeader(h)
for _, d := range data {
e := []string{d.ID.String(), strconv.FormatBool(d.Default), strconv.FormatBool(d.DenyDashboardAccess), strconv.FormatBool(d.FullAccess)}
if !platformRoles {
e = append(e, d.NetworkID.String())
}
table.Append(e)
}
table.Render()
}
},
}
var userRoleCreateCmd = &cobra.Command{
Use: "create",
Args: cobra.NoArgs,
Short: "create user role",
Long: `create user role`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("CLI doesn't support creation of roles currently. Visit the dashboard to create one or refer to our api documentation https://docs.v2.netmaker.io/reference")
},
}
var userRoleDeleteCmd = &cobra.Command{
Use: "delete [roleID]",
Args: cobra.ExactArgs(1),
Short: "delete user role",
Long: `delete user role`,
Run: func(cmd *cobra.Command, args []string) {
resp := functions.DeleteUserRole(args[0])
if resp != nil {
fmt.Println(resp.Message)
}
},
}
var userRoleGetCmd = &cobra.Command{
Use: "get [roleID]",
Args: cobra.ExactArgs(1),
Short: "get user role",
Long: `get user role`,
Run: func(cmd *cobra.Command, args []string) {
d := functions.GetUserRole(args[0])
switch commons.OutputFormat {
case commons.JsonOutput:
functions.PrettyPrint(d)
default:
table := tablewriter.NewWriter(os.Stdout)
h := []string{"ID", "Default Role", "Dashboard Access", "Full Access"}
if d.NetworkID != "" {
h = append(h, "Network")
}
table.SetHeader(h)
e := []string{d.ID.String(), strconv.FormatBool(d.Default), strconv.FormatBool(!d.DenyDashboardAccess), strconv.FormatBool(d.FullAccess)}
if !platformRoles {
e = append(e, d.NetworkID.String())
}
table.Append(e)
table.Render()
}
},
}
func init() {
rootCmd.AddCommand(userRoleCmd)
// list roles cmd
userRoleListCmd.Flags().BoolVar(&platformRoles, "platform-roles", true,
"set to false to list network roles. By default it will only list platform roles")
userRoleCmd.AddCommand(userRoleListCmd)
// create roles cmd
userRoleCmd.AddCommand(userRoleCreateCmd)
// delete role cmd
userRoleCmd.AddCommand(userRoleDeleteCmd)
// Get Role
userRoleCmd.AddCommand(userRoleGetCmd)
}

View file

@ -1,6 +1,8 @@
package user package user
import ( import (
"strings"
"github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -12,14 +14,40 @@ var userUpdateCmd = &cobra.Command{
Short: "Update a user", Short: "Update a user",
Long: `Update a user`, Long: `Update a user`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
user := &models.User{UserName: args[0], IsAdmin: admin} user := &models.User{UserName: args[0]}
if platformID != "" {
user.PlatformRoleID = models.UserRoleID(platformID)
}
if len(networkRoles) > 0 {
netRolesMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
for netID, netRoles := range networkRoles {
roleMap := make(map[models.UserRoleID]struct{})
for _, roleID := range strings.Split(netRoles, ",") {
roleMap[models.UserRoleID(roleID)] = struct{}{}
}
netRolesMap[models.NetworkID(netID)] = roleMap
}
user.NetworkRoles = netRolesMap
}
if len(groups) > 0 {
grMap := make(map[models.UserGroupID]struct{})
for _, groupID := range groups {
grMap[models.UserGroupID(groupID)] = struct{}{}
}
user.UserGroups = grMap
}
functions.PrettyPrint(functions.UpdateUser(user)) functions.PrettyPrint(functions.UpdateUser(user))
}, },
} }
func init() { func init() {
userUpdateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ?")
userUpdateCmd.Flags().StringVar(&networks, "networks", "", "List of networks the user will access to (comma separated)") userUpdateCmd.Flags().StringVar(&password, "password", "", "Password of the user")
userUpdateCmd.Flags().StringVar(&groups, "groups", "", "List of user groups the user will be part of (comma separated)") userUpdateCmd.Flags().StringVarP(&platformID, "platform-role", "r", "",
"Platform Role of the user; run `nmctl roles list` to see available user roles")
userUpdateCmd.PersistentFlags().StringToStringVarP(&networkRoles, "network-roles", "n", nil,
"Mapping of networkID and list of roles user will be part of (comma separated)")
userUpdateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ? (deprecated v0.25.0 onwards)")
userUpdateCmd.Flags().StringArrayVarP(&groups, "groups", "g", nil, "List of user groups the user will be part of (comma separated)")
rootCmd.AddCommand(userUpdateCmd) rootCmd.AddCommand(userUpdateCmd)
} }

View file

@ -86,7 +86,7 @@ func GetCurrentContext() (name string, ctx Context) {
return return
} }
} }
log.Fatalf("No current context set, do so via `netmaker context use <name>`") log.Fatalf("No current context set, do so via `nmctl context use <name>`")
return return
} }

View file

@ -1,6 +1,8 @@
package functions package functions
import ( import (
"encoding/json"
"fmt"
"net/http" "net/http"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
@ -18,7 +20,7 @@ func CreateUser(payload *models.User) *models.User {
// UpdateUser - update a user // UpdateUser - update a user
func UpdateUser(payload *models.User) *models.User { func UpdateUser(payload *models.User) *models.User {
return request[models.User](http.MethodPut, "/api/users/networks/"+payload.UserName, payload) return request[models.User](http.MethodPut, "/api/users/"+payload.UserName, payload)
} }
// DeleteUser - delete a user // DeleteUser - delete a user
@ -35,3 +37,38 @@ func GetUser(username string) *models.User {
func ListUsers() *[]models.ReturnUser { func ListUsers() *[]models.ReturnUser {
return request[[]models.ReturnUser](http.MethodGet, "/api/users", nil) return request[[]models.ReturnUser](http.MethodGet, "/api/users", nil)
} }
func ListUserRoles() (roles []models.UserRolePermissionTemplate) {
resp := request[models.SuccessResponse](http.MethodGet, "/api/v1/users/roles", nil)
d, _ := json.Marshal(resp.Response)
json.Unmarshal(d, &roles)
return
}
func DeleteUserRole(roleID string) *models.SuccessResponse {
return request[models.SuccessResponse](http.MethodDelete, fmt.Sprintf("/api/v1/users/role?role_id=%s", roleID), nil)
}
func GetUserRole(roleID string) (role models.UserRolePermissionTemplate) {
resp := request[models.SuccessResponse](http.MethodGet, fmt.Sprintf("/api/v1/users/role?role_id=%s", roleID), nil)
d, _ := json.Marshal(resp.Response)
json.Unmarshal(d, &role)
return
}
func ListUserGrps() (groups []models.UserGroup) {
resp := request[models.SuccessResponse](http.MethodGet, "/api/v1/users/groups", nil)
d, _ := json.Marshal(resp.Response)
json.Unmarshal(d, &groups)
return
}
func DeleteUserGrp(grpID string) *models.SuccessResponse {
return request[models.SuccessResponse](http.MethodDelete, fmt.Sprintf("/api/v1/users/group?group_id=%s", grpID), nil)
}
func GetUserGrp(grpID string) (group models.UserGroup) {
resp := request[models.SuccessResponse](http.MethodGet, fmt.Sprintf("/api/v1/users/group?group_id=%s", grpID), nil)
d, _ := json.Marshal(resp.Response)
json.Unmarshal(d, &group)
return
}

View file

@ -297,7 +297,9 @@ func UpdateUser(userchange, user *models.User) (*models.User, error) {
} }
// Reset Gw Access for service users // Reset Gw Access for service users
go UpdateUserGwAccess(*user, *userchange) go UpdateUserGwAccess(*user, *userchange)
user.PlatformRoleID = userchange.PlatformRoleID if userchange.PlatformRoleID != "" {
user.PlatformRoleID = userchange.PlatformRoleID
}
user.UserGroups = userchange.UserGroups user.UserGroups = userchange.UserGroups
user.NetworkRoles = userchange.NetworkRoles user.NetworkRoles = userchange.NetworkRoles
err := ValidateUser(user) err := ValidateUser(user)
@ -325,7 +327,7 @@ func ValidateUser(user *models.User) error {
// check if role is valid // check if role is valid
_, err := GetRole(user.PlatformRoleID) _, err := GetRole(user.PlatformRoleID)
if err != nil { if err != nil {
return err return errors.New("failed to fetch platform role " + user.PlatformRoleID.String())
} }
v := validator.New() v := validator.New()
_ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool { _ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool {