github.com/esnet/gdg@v0.6.1-0.20240412190737-6b6eba9c14d8/cli/tools/organizations.go (about)

     1  package tools
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"github.com/bep/simplecobra"
     8  	"github.com/esnet/gdg/cli/support"
     9  	"github.com/esnet/gdg/internal/config"
    10  	"github.com/jedib0t/go-pretty/v6/table"
    11  	"github.com/spf13/cobra"
    12  	"log"
    13  	"log/slog"
    14  	"strconv"
    15  )
    16  
    17  func newOrgCommand() simplecobra.Commander {
    18  	return &support.SimpleCommand{
    19  		NameP: "organizations",
    20  		Short: "Manage organizations",
    21  		Long:  "Manage organizations",
    22  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
    23  			return cd.CobraCommand.Help()
    24  
    25  		},
    26  		WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
    27  			cmd.Aliases = []string{"org", "orgs"}
    28  		},
    29  		CommandsList: []simplecobra.Commander{
    30  			newSetOrgCmd(),
    31  			newGetUserOrgCmd(),
    32  			newGetTokenOrgCmd(),
    33  			//Users
    34  			newListUsers(),
    35  			newUpdateUserRoleCmd(),
    36  			newAddUserRoleCmd(),
    37  			newDeleteUserRoleCmd(),
    38  			//Preferences
    39  			newOrgPreferenceCommand(),
    40  		},
    41  	}
    42  
    43  }
    44  
    45  func newSetOrgCmd() simplecobra.Commander {
    46  	return &support.SimpleCommand{
    47  		NameP: "set",
    48  		Short: "Set --orgSlugName --orgName to set user Org",
    49  		Long:  "Set --orgSlugName --orgName to set user Org",
    50  		WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
    51  			cmd.PersistentFlags().StringP("orgName", "o", "", "Set user Org by Name (not slug)")
    52  			cmd.PersistentFlags().StringP("orgSlugName", "", "", "Set user Org by slug name")
    53  
    54  		},
    55  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
    56  			orgName, _ := cd.CobraCommand.Flags().GetString("orgName")
    57  			slugName, _ := cd.CobraCommand.Flags().GetString("orgSlugName")
    58  			if orgName == "" && slugName == "" {
    59  				return errors.New("must set either --orgName or --orgSlugName flag")
    60  			}
    61  			if orgName != "" || slugName != "" {
    62  				var useSlug = false
    63  				if slugName != "" {
    64  					useSlug = true
    65  					orgName = slugName
    66  				}
    67  				err := rootCmd.GrafanaSvc().SetOrganizationByName(orgName, useSlug)
    68  				if err != nil {
    69  					log.Fatal("unable to set Org ID, ", err.Error())
    70  				}
    71  			}
    72  
    73  			rootCmd.GrafanaSvc().InitOrganizations()
    74  			userOrg := rootCmd.GrafanaSvc().GetUserOrganization()
    75  			slog.Info("New Org is now set to", slog.String("orgName", userOrg.Name))
    76  
    77  			return nil
    78  
    79  		},
    80  	}
    81  
    82  }
    83  
    84  func newGetUserOrgCmd() simplecobra.Commander {
    85  	description := "display org associated with user"
    86  	return &support.SimpleCommand{
    87  		NameP: "userOrg",
    88  		Short: description,
    89  		Long:  description,
    90  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
    91  			slog.Info("Listing organizations for context", "context", config.Config().GetGDGConfig().GetContext())
    92  			rootCmd.TableObj.AppendHeader(table.Row{"id", "name"})
    93  			org := rootCmd.GrafanaSvc().GetUserOrganization()
    94  			if org == nil {
    95  				slog.Info("No organizations found")
    96  			} else {
    97  				rootCmd.TableObj.AppendRow(table.Row{org.ID, org.Name})
    98  				rootCmd.Render(cd.CobraCommand, map[string]interface{}{"id": org.ID, "name": org.Name})
    99  			}
   100  			return nil
   101  
   102  		},
   103  	}
   104  
   105  }
   106  
   107  func newGetTokenOrgCmd() simplecobra.Commander {
   108  	description := "display org associated with token"
   109  	return &support.SimpleCommand{
   110  		NameP: "tokenOrg",
   111  		Short: description,
   112  		Long:  description,
   113  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
   114  
   115  			slog.Info("Display token organization for context'", "context", config.Config().GetGDGConfig().GetContext())
   116  			rootCmd.TableObj.AppendHeader(table.Row{"id", "name"})
   117  			org := rootCmd.GrafanaSvc().GetTokenOrganization()
   118  			if org == nil {
   119  				slog.Info("No tokens were found")
   120  			} else {
   121  				rootCmd.TableObj.AppendRow(table.Row{org.ID, org.Name})
   122  				rootCmd.Render(cd.CobraCommand, map[string]interface{}{"id": org.ID, "name": org.Name})
   123  			}
   124  			return nil
   125  		},
   126  	}
   127  
   128  }
   129  
   130  func newListUsers() simplecobra.Commander {
   131  	description := "listUsers <orgId> list an Organization users"
   132  	return &support.SimpleCommand{
   133  		NameP: "listUsers",
   134  		Short: description,
   135  		Long:  description,
   136  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
   137  			if len(args) < 1 {
   138  				return errors.New("requires an orgId to be specified")
   139  			}
   140  			orgId, err := strconv.ParseInt(args[0], 10, 64)
   141  			if err != nil {
   142  				log.Fatal("unable to parse orgId to numeric value")
   143  			}
   144  			slog.Info("Listing org users for context", "context", config.Config().GetGDGConfig().GetContext())
   145  			rootCmd.TableObj.AppendHeader(table.Row{"id", "login", "orgId", "name", "email", "role"})
   146  			users := rootCmd.GrafanaSvc().ListOrgUsers(orgId)
   147  			if len(users) == 0 {
   148  				slog.Info("No users found")
   149  			} else {
   150  				for _, user := range users {
   151  					rootCmd.TableObj.AppendRow(table.Row{user.UserID, user.Login, user.OrgID, user.Name, user.Email, user.Role})
   152  				}
   153  				rootCmd.Render(cd.CobraCommand, users)
   154  			}
   155  			return nil
   156  		},
   157  	}
   158  
   159  }
   160  
   161  func newUpdateUserRoleCmd() simplecobra.Commander {
   162  	description := "updateUserRole <orgSlugName> <userId> <role>"
   163  	return &support.SimpleCommand{
   164  		NameP: "updateUserRole",
   165  		Short: description,
   166  		Long:  description,
   167  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
   168  			if len(args) < 3 {
   169  				return fmt.Errorf("requires the following parameters to be specified: [<orgId> <userId> <role>]\nValid roles are: [admin, editor, viewer]")
   170  			}
   171  			orgSlug := args[0]
   172  			roleName := args[2]
   173  			userId, err := strconv.ParseInt(args[1], 10, 64)
   174  			if err != nil {
   175  				log.Fatal("unable to parse userId to numeric value")
   176  			}
   177  			slog.Info("Updating User role for context", "context", config.Config().GetGDGConfig().GetContext())
   178  			rootCmd.TableObj.AppendHeader(table.Row{"login", "orgId", "name", "email", "role"})
   179  			err = rootCmd.GrafanaSvc().UpdateUserInOrg(roleName, orgSlug, userId)
   180  			if err != nil {
   181  				slog.Error("Unable to update Org user")
   182  			} else {
   183  				slog.Info("User has been updated")
   184  			}
   185  			return nil
   186  		},
   187  	}
   188  }
   189  
   190  func newAddUserRoleCmd() simplecobra.Commander {
   191  	description := "addUser <orgSlugName> <userId> <role>"
   192  	return &support.SimpleCommand{
   193  		NameP: "addUser",
   194  		Short: description,
   195  		Long:  description,
   196  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
   197  			if len(args) < 3 {
   198  				return fmt.Errorf("requires the following parameters to be specified: [<orgSlugName> <userId> <role>]\nValid roles are: [admin, editor, viewer]")
   199  			}
   200  			orgSlug := args[0]
   201  			userId, err := strconv.ParseInt(args[1], 10, 64)
   202  			if err != nil {
   203  				log.Fatal("unable to parse userId to numeric value")
   204  			}
   205  			slog.Info("Adding user to org for context",
   206  				slog.Any("userId", userId), slog.String("orgSlug", orgSlug),
   207  				slog.String("context", config.Config().GetGDGConfig().GetContext()),
   208  				slog.String("orgSlug", orgSlug),
   209  			)
   210  			rootCmd.TableObj.AppendHeader(table.Row{"login", "orgId", "name", "email", "role"})
   211  			err = rootCmd.GrafanaSvc().AddUserToOrg(args[2], orgSlug, userId)
   212  			if err != nil {
   213  				slog.Error("Unable to add user to Org, already exists", slog.Any("userId", userId), slog.String("orgSlug", orgSlug))
   214  			} else {
   215  				slog.Info("User has been add to Org", slog.Any("userId", userId), slog.String("organization", orgSlug))
   216  			}
   217  			return nil
   218  		},
   219  	}
   220  }
   221  
   222  func newDeleteUserRoleCmd() simplecobra.Commander {
   223  	description := "deleteUser <orgSlug> <userId> removes a user from the given Organization (This will NOT delete the actual user from Grafana)"
   224  	return &support.SimpleCommand{
   225  		NameP: "deleteUser",
   226  		Short: description,
   227  		Long:  description,
   228  		RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
   229  			if len(args) < 2 {
   230  				return fmt.Errorf("requires the following parameters to be specified: [<orgSlugName> <userId>]")
   231  			}
   232  			orgSlug := args[0]
   233  			userId, err := strconv.ParseInt(args[1], 10, 64)
   234  
   235  			if err != nil {
   236  				log.Fatal("unable to parse userId to numeric value")
   237  			}
   238  			slog.Info("Update org for context", "context", config.Config().GetGDGConfig().GetContext())
   239  			err = rootCmd.GrafanaSvc().DeleteUserFromOrg(orgSlug, userId)
   240  			if err != nil {
   241  				slog.Error("Unable to remove user from Org")
   242  			} else {
   243  				slog.Info("User has been removed from Org", "userId", args[0])
   244  			}
   245  			return nil
   246  		},
   247  	}
   248  }