2018-05-16 18:59:35 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-11-20 00:55:36 +00:00
|
|
|
"errors"
|
2018-05-16 18:59:35 +00:00
|
|
|
"os"
|
|
|
|
|
2019-01-08 00:37:16 +00:00
|
|
|
platform "github.com/influxdata/influxdb"
|
|
|
|
"github.com/influxdata/influxdb/cmd/influx/internal"
|
|
|
|
"github.com/influxdata/influxdb/http"
|
2018-05-16 18:59:35 +00:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
func userCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "user",
|
|
|
|
Short: "User management commands",
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
cmd.Usage()
|
|
|
|
},
|
|
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
|
|
userCreateCmd(),
|
|
|
|
userDeleteCmd(),
|
|
|
|
userFindCmd(),
|
|
|
|
userUpdateCmd(),
|
|
|
|
)
|
|
|
|
|
|
|
|
return cmd
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
var userUpdateFlags struct {
|
2018-05-16 18:59:35 +00:00
|
|
|
id string
|
|
|
|
name string
|
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
func userUpdateCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
2018-05-16 18:59:35 +00:00
|
|
|
Use: "update",
|
|
|
|
Short: "Update user",
|
2019-01-22 18:19:26 +00:00
|
|
|
RunE: wrapCheckSetup(userUpdateF),
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
cmd.Flags().StringVarP(&userUpdateFlags.id, "id", "i", "", "The user ID (required)")
|
|
|
|
cmd.Flags().StringVarP(&userUpdateFlags.name, "name", "n", "", "The user name")
|
|
|
|
cmd.MarkFlagRequired("id")
|
2018-05-16 18:59:35 +00:00
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
return cmd
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 23:28:43 +00:00
|
|
|
func newUserService() (platform.UserService, error) {
|
2018-10-25 19:28:33 +00:00
|
|
|
if flags.local {
|
2019-03-28 08:42:38 +00:00
|
|
|
return newLocalKVService()
|
2018-10-25 19:28:33 +00:00
|
|
|
}
|
2019-12-17 20:17:43 +00:00
|
|
|
|
|
|
|
client, err := newHTTPClient()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-10-25 19:28:33 +00:00
|
|
|
return &http.UserService{
|
2019-12-17 20:17:43 +00:00
|
|
|
Client: client,
|
2018-10-25 19:28:33 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-11-14 23:28:43 +00:00
|
|
|
func newUserResourceMappingService() (platform.UserResourceMappingService, error) {
|
2018-10-25 19:28:33 +00:00
|
|
|
if flags.local {
|
2019-03-28 08:42:38 +00:00
|
|
|
return newLocalKVService()
|
2018-10-25 19:28:33 +00:00
|
|
|
}
|
2019-12-07 18:54:03 +00:00
|
|
|
|
|
|
|
c, err := newHTTPClient()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-10-25 19:28:33 +00:00
|
|
|
return &http.UserResourceMappingService{
|
2019-12-07 18:54:03 +00:00
|
|
|
Client: c,
|
2018-10-25 19:28:33 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-01-22 18:19:26 +00:00
|
|
|
func userUpdateF(cmd *cobra.Command, args []string) error {
|
2019-11-14 23:28:43 +00:00
|
|
|
s, err := newUserService()
|
2018-10-25 19:28:33 +00:00
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var id platform.ID
|
|
|
|
if err := id.DecodeFromString(userUpdateFlags.id); err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
update := platform.UserUpdate{}
|
|
|
|
if userUpdateFlags.name != "" {
|
|
|
|
update.Name = &userUpdateFlags.name
|
|
|
|
}
|
|
|
|
|
|
|
|
user, err := s.UpdateUser(context.Background(), id, update)
|
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
w := internal.NewTabWriter(os.Stdout)
|
|
|
|
w.WriteHeaders(
|
|
|
|
"ID",
|
|
|
|
"Name",
|
|
|
|
)
|
|
|
|
w.Write(map[string]interface{}{
|
|
|
|
"ID": user.ID.String(),
|
|
|
|
"Name": user.Name,
|
|
|
|
})
|
|
|
|
w.Flush()
|
2019-01-22 18:19:26 +00:00
|
|
|
|
|
|
|
return nil
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
var userCreateFlags struct {
|
|
|
|
name string
|
|
|
|
password string
|
2019-12-17 19:55:35 +00:00
|
|
|
organization
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
func userCreateCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
2018-05-16 18:59:35 +00:00
|
|
|
Use: "create",
|
|
|
|
Short: "Create user",
|
2019-01-22 18:19:26 +00:00
|
|
|
RunE: wrapCheckSetup(userCreateF),
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
cmd.Flags().StringVarP(&userCreateFlags.name, "name", "n", "", "The user name (required)")
|
|
|
|
cmd.MarkFlagRequired("name")
|
|
|
|
cmd.Flags().StringVarP(&userCreateFlags.password, "password", "p", "", "The user password")
|
2019-12-17 19:55:35 +00:00
|
|
|
userCreateFlags.organization.register(cmd)
|
2018-05-16 18:59:35 +00:00
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
return cmd
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 18:19:26 +00:00
|
|
|
func userCreateF(cmd *cobra.Command, args []string) error {
|
2019-12-17 19:55:35 +00:00
|
|
|
if err := userCreateFlags.organization.validOrgFlags(); err != nil {
|
|
|
|
return err
|
2019-12-10 23:46:36 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 23:28:43 +00:00
|
|
|
s, err := newUserService()
|
2018-10-25 19:28:33 +00:00
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
user := &platform.User{
|
|
|
|
Name: userCreateFlags.name,
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.CreateUser(context.Background(), user); err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
writeOutput := func(headers []string, vals ...string) error {
|
|
|
|
if len(headers) != len(vals) {
|
|
|
|
return errors.New("invalid headers and val setup for writer")
|
|
|
|
}
|
|
|
|
|
|
|
|
m := make(map[string]interface{})
|
|
|
|
for i, h := range headers {
|
|
|
|
m[h] = vals[i]
|
|
|
|
}
|
|
|
|
w := internal.NewTabWriter(os.Stdout)
|
|
|
|
w.WriteHeaders(headers...)
|
|
|
|
w.Write(m)
|
|
|
|
w.Flush()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-12-12 17:33:15 +00:00
|
|
|
orgSVC, err := newOrganizationService()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-12-10 23:46:36 +00:00
|
|
|
|
2019-12-17 19:55:35 +00:00
|
|
|
orgID, err := userCreateFlags.organization.getID(orgSVC)
|
2019-12-12 17:33:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2019-12-10 23:46:36 +00:00
|
|
|
}
|
2019-12-12 17:33:15 +00:00
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
pass := userCreateFlags.password
|
2019-12-12 17:33:15 +00:00
|
|
|
if orgID == 0 && pass == "" {
|
2019-11-20 00:55:36 +00:00
|
|
|
return writeOutput([]string{"ID", "Name"}, user.ID.String(), user.Name)
|
|
|
|
}
|
|
|
|
|
2019-12-12 17:33:15 +00:00
|
|
|
if pass != "" && orgID == 0 {
|
2019-11-20 00:55:36 +00:00
|
|
|
return errors.New("an org id is required when providing a user password")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2019-12-12 17:33:15 +00:00
|
|
|
return errors.New("an invalid org ID provided: " + orgID.GoString())
|
2019-11-20 00:55:36 +00:00
|
|
|
}
|
|
|
|
|
2019-12-07 18:54:03 +00:00
|
|
|
c, err := newHTTPClient()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
userResMapSVC := &http.UserResourceMappingService{
|
2019-12-07 18:54:03 +00:00
|
|
|
Client: c,
|
2019-11-20 00:55:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = userResMapSVC.CreateUserResourceMapping(context.Background(), &platform.UserResourceMapping{
|
|
|
|
UserID: user.ID,
|
|
|
|
UserType: platform.Member,
|
|
|
|
ResourceType: platform.OrgsResourceType,
|
2019-12-12 17:33:15 +00:00
|
|
|
ResourceID: orgID,
|
2018-05-16 18:59:35 +00:00
|
|
|
})
|
2019-11-20 00:55:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-01-22 18:19:26 +00:00
|
|
|
|
2019-12-17 20:17:43 +00:00
|
|
|
passSVC := &http.PasswordService{Client: c}
|
2019-11-20 00:55:36 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
if err := passSVC.SetPassword(ctx, user.ID, pass); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return writeOutput([]string{"ID", "Name", "Organization ID"}, user.ID.String(), user.Name, orgID.String())
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
var userFindFlags struct {
|
2018-05-16 18:59:35 +00:00
|
|
|
id string
|
|
|
|
name string
|
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
func userFindCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
2018-05-16 18:59:35 +00:00
|
|
|
Use: "find",
|
|
|
|
Short: "Find user",
|
2019-01-22 18:19:26 +00:00
|
|
|
RunE: wrapCheckSetup(userFindF),
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
cmd.Flags().StringVarP(&userFindFlags.id, "id", "i", "", "The user ID")
|
|
|
|
cmd.Flags().StringVarP(&userFindFlags.name, "name", "n", "", "The user name")
|
2018-05-16 18:59:35 +00:00
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
return cmd
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 18:19:26 +00:00
|
|
|
func userFindF(cmd *cobra.Command, args []string) error {
|
2019-11-14 23:28:43 +00:00
|
|
|
s, err := newUserService()
|
2018-10-25 19:28:33 +00:00
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
filter := platform.UserFilter{}
|
|
|
|
if userFindFlags.name != "" {
|
|
|
|
filter.Name = &userFindFlags.name
|
|
|
|
}
|
|
|
|
if userFindFlags.id != "" {
|
2018-07-20 10:24:07 +00:00
|
|
|
id, err := platform.IDFromString(userFindFlags.id)
|
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
2018-07-20 10:24:07 +00:00
|
|
|
filter.ID = id
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
users, _, err := s.FindUsers(context.Background(), filter)
|
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
w := internal.NewTabWriter(os.Stdout)
|
|
|
|
w.WriteHeaders(
|
|
|
|
"ID",
|
|
|
|
"Name",
|
|
|
|
)
|
|
|
|
for _, u := range users {
|
|
|
|
w.Write(map[string]interface{}{
|
|
|
|
"ID": u.ID.String(),
|
|
|
|
"Name": u.Name,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
w.Flush()
|
2019-01-22 18:19:26 +00:00
|
|
|
|
|
|
|
return nil
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
var userDeleteFlags struct {
|
2018-05-16 18:59:35 +00:00
|
|
|
id string
|
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
func userDeleteCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
2018-05-16 18:59:35 +00:00
|
|
|
Use: "delete",
|
|
|
|
Short: "Delete user",
|
2019-01-22 18:19:26 +00:00
|
|
|
RunE: wrapCheckSetup(userDeleteF),
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
cmd.Flags().StringVarP(&userDeleteFlags.id, "id", "i", "", "The user ID (required)")
|
|
|
|
cmd.MarkFlagRequired("id")
|
2018-05-16 18:59:35 +00:00
|
|
|
|
2019-11-20 00:55:36 +00:00
|
|
|
return cmd
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 18:19:26 +00:00
|
|
|
func userDeleteF(cmd *cobra.Command, args []string) error {
|
2019-11-14 23:28:43 +00:00
|
|
|
s, err := newUserService()
|
2018-10-25 19:28:33 +00:00
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var id platform.ID
|
|
|
|
if err := id.DecodeFromString(userDeleteFlags.id); err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 18:19:26 +00:00
|
|
|
ctx := context.Background()
|
2018-05-16 18:59:35 +00:00
|
|
|
u, err := s.FindUserByID(ctx, id)
|
|
|
|
if err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.DeleteUser(ctx, id); err != nil {
|
2019-01-22 18:19:26 +00:00
|
|
|
return err
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
w := internal.NewTabWriter(os.Stdout)
|
|
|
|
w.WriteHeaders(
|
|
|
|
"ID",
|
|
|
|
"Name",
|
|
|
|
"Deleted",
|
|
|
|
)
|
|
|
|
w.Write(map[string]interface{}{
|
|
|
|
"ID": u.ID.String(),
|
|
|
|
"Name": u.Name,
|
|
|
|
"Deleted": true,
|
|
|
|
})
|
|
|
|
w.Flush()
|
2019-01-22 18:19:26 +00:00
|
|
|
|
|
|
|
return nil
|
2018-05-16 18:59:35 +00:00
|
|
|
}
|