diff --git a/cmd/list.go b/cmd/list.go index af74ca2f..480e6aba 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -16,6 +16,7 @@ import ( "github.com/uselagoon/lagoon-cli/pkg/output" l "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" + ls "github.com/uselagoon/machinery/api/schema" ) // ListFlags . @@ -367,24 +368,168 @@ var listTasksCmd = &cobra.Command{ } var listUsersCmd = &cobra.Command{ - //@TODO: once individual user interaction comes in, this will need to be adjusted - Use: "users", - Aliases: []string{"u"}, - Short: "List all users in groups (alias: u)", - Long: `List all users in groups in lagoon, this only shows users that are in groups.`, - Run: func(cmd *cobra.Command, args []string) { - returnedJSON, err := uClient.ListUsers(groupName) - handleError(err) + Use: "group-users", + Aliases: []string{"gu"}, + Short: "List all users in groups", + Long: `List all users in groups in lagoon, this only shows users that are in groups. +If no group name is provided, all groups are queried. +Without a group name, this query may time out in large Lagoon installs.`, + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + data := []output.Data{} + if groupName != "" { + // if a groupName is provided, use the groupbyname resolver + groupMembers, err := l.ListGroupMembers(context.TODO(), groupName, lc) + if err != nil { + return err + } + for _, member := range groupMembers.Members { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%s", groupMembers.ID)), + returnNonEmptyString(fmt.Sprintf("%s", groupMembers.Name)), + returnNonEmptyString(fmt.Sprintf("%s", member.User.Email)), + returnNonEmptyString(fmt.Sprintf("%s", member.Role)), + }) + } + } else { + // otherwise allgroups query + groupMembers, err := l.ListAllGroupMembers(context.TODO(), groupName, lc) + if err != nil { + return err + } + for _, group := range *groupMembers { + for _, member := range group.Members { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%s", group.ID)), + returnNonEmptyString(fmt.Sprintf("%s", group.Name)), + returnNonEmptyString(fmt.Sprintf("%s", member.User.Email)), + returnNonEmptyString(fmt.Sprintf("%s", member.Role)), + }) + } + } + } + dataMain := output.Table{ + Header: []string{"ID", "GroupName", "Email", "Role"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo("There are no users in any groups", outputOptions) - os.Exit(0) +var listAllUsersCmd = &cobra.Command{ + Use: "all-users", + Aliases: []string{"au"}, + Short: "List all users", + Long: `List all users. +This query can take a long time to run if there are a lot of users.`, + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + emailAddress, err := cmd.Flags().GetString("email-address") + if err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + allUsers, err := l.AllUsers(context.TODO(), ls.AllUsersFilter{ + Email: emailAddress, + }, lc) + if err != nil { + return err + } + data := []output.Data{} + for _, user := range *allUsers { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%s", user.ID)), + returnNonEmptyString(fmt.Sprintf("%s", user.Email)), + returnNonEmptyString(fmt.Sprintf("%s", user.FirstName)), + returnNonEmptyString(fmt.Sprintf("%s", user.LastName)), + returnNonEmptyString(fmt.Sprintf("%s", user.Comment)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Email", "FirstName", "LastName", "Comment"}, + Data: data, } output.RenderOutput(dataMain, outputOptions) + return nil + }, +} +var listUsersGroupsCmd = &cobra.Command{ + Use: "user-groups", + Aliases: []string{"ug"}, + Short: "List a single users groups and roles", + Long: `List a single users groups and roles`, + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + emailAddress, err := cmd.Flags().GetString("email-address") + if err != nil { + return err + } + if emailAddress == "" { + return fmt.Errorf("Missing arguments: email address is not defined") + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + allUsers, err := l.GetUserByEmail(context.TODO(), emailAddress, lc) + if err != nil { + return err + } + data := []output.Data{} + for _, grouprole := range allUsers.GroupRoles { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%s", allUsers.ID)), + returnNonEmptyString(fmt.Sprintf("%s", allUsers.Email)), + returnNonEmptyString(fmt.Sprintf("%s", grouprole.Name)), + returnNonEmptyString(fmt.Sprintf("%s", grouprole.Role)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Email", "GroupName", "GroupRole"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -768,6 +913,10 @@ func init() { listCmd.AddCommand(listInvokableTasks) listCmd.AddCommand(listBackupsCmd) listCmd.AddCommand(listDeployTargetConfigsCmd) + listCmd.AddCommand(listAllUsersCmd) + listCmd.AddCommand(listUsersGroupsCmd) + listAllUsersCmd.Flags().StringP("email-address", "E", "", "The email address of a user") + listUsersGroupsCmd.Flags().StringP("email-address", "E", "", "The email address of a user") listCmd.AddCommand(listOrganizationCmd) listOrganizationCmd.AddCommand(listOrganizationProjectsCmd) listOrganizationCmd.AddCommand(ListOrganizationUsersCmd) @@ -775,7 +924,7 @@ func init() { listOrganizationCmd.AddCommand(listOrganizationDeployTargetsCmd) listOrganizationCmd.AddCommand(listOrganizationsCmd) listCmd.Flags().BoolVarP(&listAllProjects, "all-projects", "", false, "All projects (if supported)") - listUsersCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group to list users in (if not specified, will default to all groups)") + listUsersCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group to list users in") listGroupProjectsCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group to list projects in") listVariablesCmd.Flags().BoolP("reveal", "", false, "Reveal the variable values") listOrganizationProjectsCmd.Flags().StringP("name", "O", "", "Name of the organization to list associated projects for") diff --git a/docs/commands/lagoon_list.md b/docs/commands/lagoon_list.md index 774a8467..28dc7f04 100644 --- a/docs/commands/lagoon_list.md +++ b/docs/commands/lagoon_list.md @@ -33,12 +33,14 @@ List projects, environments, deployments, variables or notifications ### SEE ALSO * [lagoon](lagoon.md) - Command line integration for Lagoon +* [lagoon list all-users](lagoon_list_all-users.md) - List all users * [lagoon list backups](lagoon_list_backups.md) - List an environments backups * [lagoon list deployments](lagoon_list_deployments.md) - List deployments for an environment (alias: d) * [lagoon list deploytarget-configs](lagoon_list_deploytarget-configs.md) - List deploytarget configs for a project * [lagoon list deploytargets](lagoon_list_deploytargets.md) - List all DeployTargets in Lagoon * [lagoon list environments](lagoon_list_environments.md) - List environments for a project (alias: e) * [lagoon list group-projects](lagoon_list_group-projects.md) - List projects in a group (alias: gp) +* [lagoon list group-users](lagoon_list_group-users.md) - List all users in groups * [lagoon list groups](lagoon_list_groups.md) - List groups you have access to (alias: g) * [lagoon list invokable-tasks](lagoon_list_invokable-tasks.md) - Print a list of invokable tasks * [lagoon list notification](lagoon_list_notification.md) - List all notifications or notifications on projects @@ -47,6 +49,6 @@ List projects, environments, deployments, variables or notifications * [lagoon list projects](lagoon_list_projects.md) - List all projects you have access to (alias: p) * [lagoon list projects-by-metadata](lagoon_list_projects-by-metadata.md) - List projects by a given metadata key or key:value * [lagoon list tasks](lagoon_list_tasks.md) - List tasks for an environment (alias: t) -* [lagoon list users](lagoon_list_users.md) - List all users in groups (alias: u) +* [lagoon list user-groups](lagoon_list_user-groups.md) - List a single users groups and roles * [lagoon list variables](lagoon_list_variables.md) - List variables for a project or environment (alias: v) diff --git a/docs/commands/lagoon_list_all-users.md b/docs/commands/lagoon_list_all-users.md new file mode 100644 index 00000000..98974c30 --- /dev/null +++ b/docs/commands/lagoon_list_all-users.md @@ -0,0 +1,41 @@ +## lagoon list all-users + +List all users + +### Synopsis + +List all users. +This query can take a long time to run if there are a lot of users. + +``` +lagoon list all-users [flags] +``` + +### Options + +``` + -E, --email-address string The email address of a user + -h, --help help for all-users +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication +``` + +### SEE ALSO + +* [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications + diff --git a/docs/commands/lagoon_list_group-users.md b/docs/commands/lagoon_list_group-users.md new file mode 100644 index 00000000..e39a7bb2 --- /dev/null +++ b/docs/commands/lagoon_list_group-users.md @@ -0,0 +1,42 @@ +## lagoon list group-users + +List all users in groups + +### Synopsis + +List all users in groups in lagoon, this only shows users that are in groups. +If no group name is provided, all groups are queried. +Without a group name, this query may time out in large Lagoon installs. + +``` +lagoon list group-users [flags] +``` + +### Options + +``` + -h, --help help for group-users + -N, --name string Name of the group to list users in +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication +``` + +### SEE ALSO + +* [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications + diff --git a/docs/commands/lagoon_list_user-groups.md b/docs/commands/lagoon_list_user-groups.md new file mode 100644 index 00000000..3d2a43f6 --- /dev/null +++ b/docs/commands/lagoon_list_user-groups.md @@ -0,0 +1,40 @@ +## lagoon list user-groups + +List a single users groups and roles + +### Synopsis + +List a single users groups and roles + +``` +lagoon list user-groups [flags] +``` + +### Options + +``` + -E, --email-address string The email address of a user + -h, --help help for user-groups +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication +``` + +### SEE ALSO + +* [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications + diff --git a/go.mod b/go.mod index c838de46..e3ab3077 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.3 github.com/stretchr/testify v1.8.2 - github.com/uselagoon/machinery v0.0.13 + github.com/uselagoon/machinery v0.0.14 golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b gopkg.in/yaml.v2 v2.2.8 sigs.k8s.io/yaml v1.2.0 @@ -39,8 +39,3 @@ require ( replace github.com/olekukonko/tablewriter => github.com/shreddedbacon/tablewriter v0.0.2-0.20200114082015-d810c4a558bf //replace github.com/uselagoon/machinery => ../machinery - -// replace github.com/olekukonko/tablewriter => ../../shreddedbacon/tablewriter - -// replace github.com/uselagoon/machinery v0.0.8 => ../machinery -replace github.com/uselagoon/machinery v0.0.8 => github.com/uselagoon/machinery v0.0.0-20230518215531-41f1b4bb9b26 diff --git a/go.sum b/go.sum index afd7c23b..b43ef6e6 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9 h1:vY5WqiEon0ZSTGM3ayVVi+twaHKHDFUVloaQ/wug9/c= github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9/go.mod h1:q+QjxYvZ+fpjMXqs+XEriussHjSYqeXVnAdSV1tkMYk= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/uselagoon/machinery v0.0.13 h1:ZCLBNWJmDr3wikaHs3pWhQ1j8MprhIqRuChgSqmLyZc= -github.com/uselagoon/machinery v0.0.13/go.mod h1:h/qeMWQR4Qqu33x+8AulNDeolEwvb/G+aIsn/jyUtwk= +github.com/uselagoon/machinery v0.0.14 h1:2w0JAgxasGXyh61yLEmvGLqVpwCm5ip02v17Wicuuio= +github.com/uselagoon/machinery v0.0.14/go.mod h1:h/qeMWQR4Qqu33x+8AulNDeolEwvb/G+aIsn/jyUtwk= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=