diff --git a/cmd/add.go b/cmd/add.go index eeb2951e..6ea38fef 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -22,6 +22,15 @@ var addNotificationCmd = &cobra.Command{ }, } +var addOrganizationCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Add an organization, or add a group/project to an organization", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + }, +} + func init() { addCmd.AddCommand(addDeployTargetCmd) addCmd.AddCommand(addGroupCmd) @@ -29,6 +38,7 @@ func init() { addCmd.AddCommand(addProjectToGroupCmd) addCmd.AddCommand(addNotificationCmd) addCmd.AddCommand(addUserCmd) + addCmd.AddCommand(addOrganizationCmd) addCmd.AddCommand(addUserToGroupCmd) addCmd.AddCommand(addUserSSHKeyCmd) addCmd.AddCommand(addVariableCmd) diff --git a/cmd/delete.go b/cmd/delete.go index aa6288af..d2e07788 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -22,6 +22,15 @@ var deleteNotificationCmd = &cobra.Command{ }, } +var deleteOrganizationCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Add an organization, or add a group/project to an organization", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + }, +} + func init() { deleteCmd.AddCommand(deleteEnvCmd) deleteCmd.AddCommand(deleteGroupCmd) @@ -34,4 +43,5 @@ func init() { deleteCmd.AddCommand(deleteUserFromGroupCmd) deleteCmd.AddCommand(deleteVariableCmd) deleteCmd.AddCommand(deleteDeployTargetConfigCmd) + deleteCmd.AddCommand(deleteOrganizationCmd) } diff --git a/cmd/deploytarget.go b/cmd/deploytarget.go index 59fe8785..e1025b33 100644 --- a/cmd/deploytarget.go +++ b/cmd/deploytarget.go @@ -3,12 +3,15 @@ package cmd import ( "context" "fmt" - "github.com/spf13/cobra" "github.com/uselagoon/lagoon-cli/internal/lagoon" "github.com/uselagoon/lagoon-cli/internal/lagoon/client" "github.com/uselagoon/lagoon-cli/internal/schema" "github.com/uselagoon/lagoon-cli/pkg/output" + l "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + s "github.com/uselagoon/machinery/api/schema" + "strconv" ) var addDeployTargetCmd = &cobra.Command{ @@ -319,6 +322,121 @@ var deleteDeployTargetCmd = &cobra.Command{ }, } +var addDeployTargetToOrganizationCmd = &cobra.Command{ + Use: "deploytarget", + Aliases: []string{"dt"}, + Short: "Add a deploy target to an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + deployTarget, err := cmd.Flags().GetUint("deploy-target") + if err != nil { + return err + } + if err := requiredInputCheck("Deploy Target", strconv.Itoa(int(deployTarget))); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + deployTargetInput := s.AddDeployTargetToOrganizationInput{ + DeployTarget: deployTarget, + Organization: organization.ID, + } + + deployTargetResponse, err := l.AddDeployTargetToOrganization(context.TODO(), &deployTargetInput, lc) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Deploy Target": deployTargetResponse.Name, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + +var RemoveDeployTargetFromOrganizationCmd = &cobra.Command{ + Use: "deploytarget", + Aliases: []string{"dt"}, + Short: "Remove a deploy target from an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + deployTarget, err := cmd.Flags().GetUint("deploy-target") + if err != nil { + return err + } + if err := requiredInputCheck("Deploy Target", strconv.Itoa(int(deployTarget))); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + deployTargetInput := s.RemoveDeployTargetFromOrganizationInput{ + DeployTarget: deployTarget, + Organization: organization.ID, + } + + if yesNo(fmt.Sprintf("You are attempting to remove deploy target '%d' from organization '%s', are you sure?", deployTarget, organization.Name)) { + _, err := l.RemoveDeployTargetFromOrganization(context.TODO(), &deployTargetInput, lc) + handleError(err) + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Deploy Target": deployTarget, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + } + return nil + }, +} + func init() { addDeployTargetCmd.Flags().UintP("id", "", 0, "ID of the DeployTarget") addDeployTargetCmd.Flags().StringP("name", "", "", "Name of DeployTarget") @@ -332,9 +450,15 @@ func init() { addDeployTargetCmd.Flags().StringP("ssh-port", "", "", "DeployTarget ssh port") addDeployTargetCmd.Flags().StringP("build-image", "", "", "DeployTarget build image to use (if different to the default)") + addDeployTargetToOrganizationCmd.Flags().StringP("name", "O", "", "Name of Organization") + addDeployTargetToOrganizationCmd.Flags().UintP("deploy-target", "D", 0, "ID of DeployTarget") + deleteDeployTargetCmd.Flags().UintP("id", "", 0, "ID of the DeployTarget") deleteDeployTargetCmd.Flags().StringP("name", "", "", "Name of DeployTarget") + RemoveDeployTargetFromOrganizationCmd.Flags().StringP("name", "O", "", "Name of Organization") + RemoveDeployTargetFromOrganizationCmd.Flags().UintP("deploy-target", "D", 0, "ID of DeployTarget") + updateDeployTargetCmd.Flags().UintP("id", "", 0, "ID of the DeployTarget") updateDeployTargetCmd.Flags().StringP("console-url", "", "", "DeployTarget console URL") updateDeployTargetCmd.Flags().StringP("token", "", "", "DeployTarget token") diff --git a/cmd/environment.go b/cmd/environment.go index f7dddd4b..75bc481a 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -124,7 +124,7 @@ var updateEnvironmentCmd = &cobra.Command{ Route: nullStrCheck(route), Routes: nullStrCheck(routes), DeployTitle: nullStrCheck(deployTitle), - Openshift: nullIntCheck(openShift), + Openshift: nullUintCheck(openShift), } if environmentAutoIdleProvided { environmentFlags.AutoIdle = &environmentAutoIdle @@ -158,20 +158,6 @@ var updateEnvironmentCmd = &cobra.Command{ }, } -func nullStrCheck(s string) *string { - if s == "" { - return nil - } - return &s -} - -func nullIntCheck(i uint) *uint { - if i == 0 { - return nil - } - return &i -} - func checkFlags(f *pflag.Flag) { if f.Name == "auto-idle" { environmentAutoIdleProvided = true diff --git a/cmd/get.go b/cmd/get.go index 193aef2c..acf45c71 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -1,14 +1,18 @@ package cmd import ( + "context" "encoding/json" "fmt" "os" + "strconv" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" + + l "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" ) // GetFlags . @@ -44,68 +48,152 @@ var getProjectCmd = &cobra.Command{ Use: "project", Aliases: []string{"p"}, Short: "Get details about a project", - Run: func(cmd *cobra.Command, args []string) { - getProjectFlags := parseGetFlags(*cmd.Flags()) - if getProjectFlags.Project == "" { + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + if cmdProjectName == "" { fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + return nil } - returnedJSON, err := pClient.GetProjectInfo(getProjectFlags.Project) + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + project, err := l.GetProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + return err } - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + + if project == nil { + output.RenderInfo(fmt.Sprintf("No details for project '%s'", cmdProjectName), outputOptions) + return nil } - if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("No details for project '%s'", getProjectFlags.Project), outputOptions) - os.Exit(0) + + DevEnvironments := 0 + productionRoute := "none" + deploymentsDisabled, err := strconv.ParseBool(strconv.Itoa(int(project.DeploymentsDisabled))) + handleError(err) + autoIdle, err := strconv.ParseBool(strconv.Itoa(int(project.AutoIdle))) + handleError(err) + factsUI, err := strconv.ParseBool(strconv.Itoa(int(project.FactsUI))) + handleError(err) + problemsUI, err := strconv.ParseBool(strconv.Itoa(int(project.ProblemsUI))) + handleError(err) + for _, environment := range project.Environments { + if environment.EnvironmentType == "development" { + DevEnvironments++ + } + if environment.EnvironmentType == "production" { + productionRoute = environment.Route + } } - output.RenderOutput(dataMain, outputOptions) + data := []output.Data{} + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", project.ID)), + returnNonEmptyString(fmt.Sprintf("%v", project.Name)), + returnNonEmptyString(fmt.Sprintf("%v", project.GitURL)), + returnNonEmptyString(fmt.Sprintf("%v", project.Branches)), + returnNonEmptyString(fmt.Sprintf("%v", project.PullRequests)), + returnNonEmptyString(fmt.Sprintf("%v", productionRoute)), + returnNonEmptyString(fmt.Sprintf("%v/%v", DevEnvironments, project.DevelopmentEnvironmentsLimit)), + returnNonEmptyString(fmt.Sprintf("%v", project.DevelopmentEnvironmentsLimit)), + returnNonEmptyString(fmt.Sprintf("%v", project.ProductionEnvironment)), + returnNonEmptyString(fmt.Sprintf("%v", project.RouterPattern)), + returnNonEmptyString(fmt.Sprintf("%v", autoIdle)), + returnNonEmptyString(fmt.Sprintf("%v", factsUI)), + returnNonEmptyString(fmt.Sprintf("%v", problemsUI)), + returnNonEmptyString(fmt.Sprintf("%v", deploymentsDisabled)), + }) + dataMain := output.Table{ + Header: []string{"ID", "ProjectName", "GitURL", "Branches", "PullRequests", "ProductionRoute", "DevEnvironments", "DevEnvLimit", "ProductionEnv", "RouterPattern", "AutoIdle", "FactsUI", "ProblemsUI", "DeploymentsDisabled"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } -var getDeploymentCmd = &cobra.Command{ +var getDeploymentByNameCmd = &cobra.Command{ Use: "deployment", Aliases: []string{"d"}, - Short: "Get a build log by remote id", - Run: func(cmd *cobra.Command, args []string) { - getProjectFlags := parseGetFlags(*cmd.Flags()) - if getProjectFlags.RemoteID == "" { - fmt.Println("Missing arguments: Remote ID is not defined") - cmd.Help() - os.Exit(1) + Short: "Get a deployment by name", + Long: `Get a deployment by name +This returns information about a deployment, the logs of this build can also be retrieved`, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err } - returnedJSON, err := eClient.GetDeploymentLog(getProjectFlags.RemoteID) + + buildName, err := cmd.Flags().GetString("name") if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + return err } - if string(returnedJSON) == "null" { - output.RenderInfo(fmt.Sprintf("No deployment for remoteId '%s'", getProjectFlags.RemoteID), outputOptions) - os.Exit(0) + showLogs, err := cmd.Flags().GetBool("logs") + if err != nil { + return err } - var deployment api.Deployment - err = json.Unmarshal([]byte(returnedJSON), &deployment) + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + deployment, err := l.GetDeploymentByName(context.TODO(), cmdProjectName, cmdProjectEnvironment, buildName, showLogs, lc) if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + return err } - if deployment.BuildLog != "" { - fmt.Println(deployment.BuildLog) - } else { - fmt.Println("Log data is not available") + if showLogs { + dataMain := output.Table{ + Header: []string{ + "Logs", + }, + Data: []output.Data{ + { + returnNonEmptyString(deployment.BuildLog), + }, + }, + } + output.RenderOutput(dataMain, outputOptions) + return nil } - + dataMain := output.Table{ + Header: []string{ + "ID", + "RemoteID", + "Name", + "Status", + "Created", + "Started", + "Completed", + }, + Data: []output.Data{ + { + returnNonEmptyString(fmt.Sprintf("%v", deployment.ID)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.RemoteID)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.Name)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.Status)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.Created)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.Started)), + returnNonEmptyString(fmt.Sprintf("%v", deployment.Completed)), + }, + }, + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } - var getEnvironmentCmd = &cobra.Command{ Use: "environment", Aliases: []string{"e"}, @@ -166,17 +254,75 @@ var getToken = &cobra.Command{ }, } +var getOrganizationCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Get details about an organization", + 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 + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + if organization.Name == "" { + output.RenderInfo(fmt.Sprintf("No organization found for '%s'", organizationName), outputOptions) + return nil + } + + data := []output.Data{} + data = append(data, []string{ + strconv.Itoa(int(organization.ID)), + organization.Name, + organization.Description, + strconv.Itoa(int(organization.QuotaProject)), + strconv.Itoa(int(organization.QuotaGroup)), + strconv.Itoa(int(organization.QuotaNotification)), + }) + + dataMain := output.Table{ + Header: []string{"ID", "Name", "Description", "Project Quota", "Group Quota", "Notification Quota"}, + Data: data, + } + + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + func init() { getCmd.AddCommand(getAllUserKeysCmd) - getCmd.AddCommand(getDeploymentCmd) getCmd.AddCommand(getEnvironmentCmd) + getCmd.AddCommand(getOrganizationCmd) getCmd.AddCommand(getProjectCmd) getCmd.AddCommand(getProjectKeyCmd) getCmd.AddCommand(getUserKeysCmd) getCmd.AddCommand(getTaskByID) getCmd.AddCommand(getToken) + getCmd.AddCommand(getDeploymentByNameCmd) getTaskByID.Flags().IntP("id", "I", 0, "ID of the task") getTaskByID.Flags().BoolP("logs", "L", false, "Show the task logs if available") getProjectKeyCmd.Flags().BoolVarP(&revealValue, "reveal", "", false, "Reveal the variable values") - getDeploymentCmd.Flags().StringVarP(&remoteID, "remoteid", "R", "", "The remote ID of the deployment") + getDeploymentByNameCmd.Flags().StringP("name", "N", "", "The name of the deployment (eg, lagoon-build-abcdef)") + getDeploymentByNameCmd.Flags().BoolP("logs", "L", false, "Show the build logs if available") + getOrganizationCmd.Flags().StringP("name", "O", "", "Name of the organization") } diff --git a/cmd/groups.go b/cmd/groups.go index f3351e6b..1dedda77 100644 --- a/cmd/groups.go +++ b/cmd/groups.go @@ -1,8 +1,12 @@ package cmd import ( + "context" "encoding/json" "fmt" + l "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + s "github.com/uselagoon/machinery/api/schema" "os" "strings" @@ -228,6 +232,67 @@ var deleteGroupCmd = &cobra.Command{ }, } +var addGroupToOrganizationCmd = &cobra.Command{ + Use: "group", + Aliases: []string{"g"}, + Short: "Add a group to an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + orgOwner, err := cmd.Flags().GetBool("org-owner") + if err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + groupName, err := cmd.Flags().GetString("group") + if err != nil { + return err + } + if err := requiredInputCheck("Group name", groupName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + groupInput := s.AddGroupToOrganizationInput{ + Name: groupName, + Organization: organization.ID, + AddOrgOwner: orgOwner, + } + group := s.OrgGroup{} + err = lc.AddGroupToOrganization(context.TODO(), &groupInput, &group) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Group Name": group.Name, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + func init() { addGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") addUserToGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") @@ -238,4 +303,7 @@ func init() { deleteUserFromGroupCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") deleteProjectFromGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") deleteGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") + addGroupToOrganizationCmd.Flags().StringP("name", "O", "", "Name of the organization") + addGroupToOrganizationCmd.Flags().StringP("group", "G", "", "Name of the group") + addGroupToOrganizationCmd.Flags().Bool("org-owner", false, "Flag to add the user to the group as an owner") } diff --git a/cmd/list.go b/cmd/list.go index 6d1a4c3a..480e6aba 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "strconv" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -581,11 +582,328 @@ var listNotificationCmd = &cobra.Command{ }, } +var listProjectGroupsCmd = &cobra.Command{ + Use: "project-groups", + Aliases: []string{"pg"}, + Short: "List groups in a project (alias: pg)", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + if cmdProjectName == "" { + fmt.Println("Missing arguments: Project is not defined") + cmd.Help() + os.Exit(1) + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + projectGroups, err := l.GetProjectGroups(context.TODO(), cmdProjectName, lc) + handleError(err) + + if len(projectGroups.Groups) == 0 { + output.RenderInfo(fmt.Sprintf("There are no projects in group '%s'", groupName), outputOptions) + os.Exit(0) + } + + data := []output.Data{} + for _, group := range projectGroups.Groups { + var organization = "null" + if group.Organization != 0 { + organization = strconv.Itoa(group.Organization) + } + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", group.ID)), + returnNonEmptyString(fmt.Sprintf("%v", group.Name)), + returnNonEmptyString(fmt.Sprintf("%v", organization)), + }) + } + dataMain := output.Table{ + Header: []string{"Group ID", "Group Name", "Organization"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var listOrganizationCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "List all organizations projects, groups, deploy targets or users", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + validateToken(lagoonCLIConfig.Current) + }, +} + +var listOrganizationProjectsCmd = &cobra.Command{ + Use: "projects", + Aliases: []string{"p"}, + Short: "List projects in an organization", + 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 + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + org, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + orgProjects, err := l.ListProjectsByOrganizationID(context.TODO(), org.ID, lc) + handleError(err) + + data := []output.Data{} + for _, project := range *orgProjects { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", project.ID)), + returnNonEmptyString(fmt.Sprintf("%s", project.Name)), + returnNonEmptyString(fmt.Sprintf("%d", project.GroupCount)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Name", "Group Count"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var listOrganizationGroupsCmd = &cobra.Command{ + Use: "groups", + Aliases: []string{"g"}, + Short: "List groups in an organization", + 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 + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + org, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + orgGroups, err := l.ListGroupsByOrganizationID(context.TODO(), org.ID, lc) + handleError(err) + + data := []output.Data{} + for _, group := range *orgGroups { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%s", group.ID.String())), + returnNonEmptyString(fmt.Sprintf("%s", group.Name)), + returnNonEmptyString(fmt.Sprintf("%s", group.Type)), + returnNonEmptyString(fmt.Sprintf("%d", group.MemberCount)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Name", "Type", "Member Count"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var listOrganizationDeployTargetsCmd = &cobra.Command{ + Use: "deploytargets", + Aliases: []string{"d"}, + Short: "List deploy targets in an organization", + 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 + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + organizationID, err := cmd.Flags().GetUint("id") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + if err := requiredInputCheck("Organization ID", strconv.Itoa(int(organizationID))); err != nil { + return err + } + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + deployTargets, err := l.ListDeployTargetsByOrganizationNameOrID(context.TODO(), nullStrCheck(organizationName), nullUintCheck(organizationID), lc) + handleError(err) + + data := []output.Data{} + for _, dt := range *deployTargets { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", dt.ID)), + returnNonEmptyString(fmt.Sprintf("%s", dt.Name)), + returnNonEmptyString(fmt.Sprintf("%s", dt.RouterPattern)), + returnNonEmptyString(fmt.Sprintf("%s", dt.CloudRegion)), + returnNonEmptyString(fmt.Sprintf("%s", dt.CloudProvider)), + returnNonEmptyString(fmt.Sprintf("%s", dt.SSHHost)), + returnNonEmptyString(fmt.Sprintf("%s", dt.SSHPort)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Name", "Router Pattern", "Cloud Region", "Cloud Provider", "SSH Host", "SSH Port"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var ListOrganizationUsersCmd = &cobra.Command{ + Use: "users", + Aliases: []string{"u"}, + Short: "List users in an organization", + 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 + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + organization, err := l.GetOrganizationByName(context.Background(), organizationName, lc) + handleError(err) + users, err := l.UsersByOrganization(context.TODO(), organization.ID, lc) + handleError(err) + + data := []output.Data{} + for _, user := range *users { + 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)), + returnNonEmptyString(fmt.Sprintf("%v", user.Owner)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Email", "First Name", "LastName", "Comment", "Owner"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var listOrganizationsCmd = &cobra.Command{ + Use: "organizations", + Aliases: []string{"o"}, + Short: "List all organizations", + 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 + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organizations, err := l.AllOrganizations(context.TODO(), lc) + + data := []output.Data{} + for _, organization := range *organizations { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", organization.ID)), + returnNonEmptyString(fmt.Sprintf("%s", organization.Name)), + returnNonEmptyString(fmt.Sprintf("%s", organization.Description)), + returnNonEmptyString(fmt.Sprintf("%d", organization.QuotaProject)), + returnNonEmptyString(fmt.Sprintf("%d", organization.QuotaGroup)), + returnNonEmptyString(fmt.Sprintf("%d", organization.QuotaNotification)), + returnNonEmptyString(fmt.Sprintf("%d", organization.QuotaEnvironment)), + returnNonEmptyString(fmt.Sprintf("%d", organization.QuotaRoute)), + }) + } + dataMain := output.Table{ + Header: []string{"ID", "Name", "Description", "Project Quota", "Group Quota", "Notification Quota", "Environment Quota", "Route Quota"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + func init() { listCmd.AddCommand(listDeployTargetsCmd) listCmd.AddCommand(listDeploymentsCmd) listCmd.AddCommand(listGroupsCmd) listCmd.AddCommand(listGroupProjectsCmd) + listCmd.AddCommand(listProjectGroupsCmd) listCmd.AddCommand(listEnvironmentsCmd) listCmd.AddCommand(listProjectsCmd) listCmd.AddCommand(listNotificationCmd) @@ -599,8 +917,19 @@ func init() { 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) + listOrganizationCmd.AddCommand(listOrganizationGroupsCmd) + 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") 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") + ListOrganizationUsersCmd.Flags().StringP("name", "O", "", "Name of the organization to list associated users for") + listOrganizationGroupsCmd.Flags().StringP("name", "O", "", "Name of the organization to list associated groups for") + listOrganizationDeployTargetsCmd.Flags().StringP("name", "O", "", "Name of the organization to list associated deploy targets for") + listOrganizationDeployTargetsCmd.Flags().Uint("id", 0, "ID of the organization to list associated deploy targets for") } diff --git a/cmd/organization.go b/cmd/organization.go new file mode 100644 index 00000000..4ca36b13 --- /dev/null +++ b/cmd/organization.go @@ -0,0 +1,250 @@ +package cmd + +import ( + "context" + "fmt" + "github.com/spf13/cobra" + "github.com/uselagoon/lagoon-cli/pkg/output" + l "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + s "github.com/uselagoon/machinery/api/schema" +) + +var addOrgCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Add a new organization to Lagoon", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + organizationFriendlyName, err := cmd.Flags().GetString("friendly-name") + if err != nil { + return err + } + organizationDescription, err := cmd.Flags().GetString("description") + if err != nil { + return err + } + organizationQuotaProject, err := cmd.Flags().GetInt("project-quota") + if err != nil { + return err + } + organizationQuotaGroup, err := cmd.Flags().GetInt("group-quota") + if err != nil { + return err + } + organizationQuotaNotification, err := cmd.Flags().GetInt("notification-quota") + if err != nil { + return err + } + organizationQuotaEnvironment, err := cmd.Flags().GetInt("environment-quota") + if err != nil { + return err + } + organizationQuotaRoute, err := cmd.Flags().GetInt("route-quota") + if err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organizationInput := s.AddOrganizationInput{ + Name: organizationName, + FriendlyName: organizationFriendlyName, + Description: organizationDescription, + QuotaProject: organizationQuotaProject, + QuotaGroup: organizationQuotaGroup, + QuotaNotification: organizationQuotaNotification, + QuotaEnvironment: organizationQuotaEnvironment, + QuotaRoute: organizationQuotaRoute, + } + org := s.Organization{} + err = lc.AddOrganization(context.TODO(), &organizationInput, &org) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + +var deleteOrgCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Delete an organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + if yesNo(fmt.Sprintf("You are attempting to delete organization '%s', are you sure?", organization.Name)) { + _, err := l.DeleteOrganization(context.TODO(), organization.ID, lc) + handleError(err) + resultData := output.Result{ + Result: organization.Name, + } + output.RenderResult(resultData, outputOptions) + } + return nil + }, +} + +var updateOrganizationCmd = &cobra.Command{ + Use: "organization", + Aliases: []string{"o"}, + Short: "Update an organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + if err != nil { + return err + } + organizationFriendlyName, err := cmd.Flags().GetString("friendly-name") + if err != nil { + return err + } + organizationDescription, err := cmd.Flags().GetString("description") + if err != nil { + return err + } + organizationQuotaProject, err := cmd.Flags().GetInt("project-quota") + if err != nil { + return err + } + organizationQuotaGroup, err := cmd.Flags().GetInt("group-quota") + if err != nil { + return err + } + organizationQuotaNotification, err := cmd.Flags().GetInt("notification-quota") + if err != nil { + return err + } + organizationQuotaEnvironment, err := cmd.Flags().GetInt("environment-quota") + if err != nil { + return err + } + organizationQuotaRoute, err := cmd.Flags().GetInt("route-quota") + if err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organizationInput := s.UpdateOrganizationPatchInput{ + Description: nullStrCheck(organizationDescription), + FriendlyName: nullStrCheck(organizationFriendlyName), + QuotaProject: nullIntCheck(organizationQuotaProject), + QuotaGroup: nullIntCheck(organizationQuotaGroup), + QuotaNotification: nullIntCheck(organizationQuotaNotification), + QuotaEnvironment: nullIntCheck(organizationQuotaEnvironment), + QuotaRoute: nullIntCheck(organizationQuotaRoute), + } + result, err := l.UpdateOrganization(context.TODO(), organization.ID, organizationInput, lc) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Organization Name": result.Name, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + +func init() { + addOrganizationCmd.AddCommand(addOrgCmd) + addOrganizationCmd.AddCommand(addGroupToOrganizationCmd) + addOrganizationCmd.AddCommand(addProjectToOrganizationCmd) + addOrganizationCmd.AddCommand(addDeployTargetToOrganizationCmd) + addOrganizationCmd.AddCommand(addUserToOrganizationCmd) + + deleteOrganizationCmd.AddCommand(deleteOrgCmd) + deleteOrganizationCmd.AddCommand(RemoveDeployTargetFromOrganizationCmd) + deleteOrganizationCmd.AddCommand(RemoveProjectFromOrganizationCmd) + deleteOrganizationCmd.AddCommand(RemoveUserFromOrganization) + + addOrgCmd.Flags().StringP("name", "O", "", "Name of the organization") + addOrgCmd.Flags().String("friendly-name", "", "Friendly name of the organization") + addOrgCmd.Flags().String("description", "", "Description of the organization") + addOrgCmd.Flags().Int("project-quota", 0, "Project quota for the organization") + addOrgCmd.Flags().Int("group-quota", 0, "Group quota for the organization") + addOrgCmd.Flags().Int("notification-quota", 0, "Notification quota for the organization") + addOrgCmd.Flags().Int("environment-quota", 0, "Environment quota for the organization") + addOrgCmd.Flags().Int("route-quota", 0, "Route quota for the organization") + + updateOrganizationCmd.Flags().StringP("name", "O", "", "Name of the organization to update") + updateOrganizationCmd.Flags().String("friendly-name", "", "Friendly name of the organization") + updateOrganizationCmd.Flags().String("description", "", "Description of the organization") + updateOrganizationCmd.Flags().Int("project-quota", 0, "Project quota for the organization") + updateOrganizationCmd.Flags().Int("group-quota", 0, "Group quota for the organization") + updateOrganizationCmd.Flags().Int("notification-quota", 0, "Notification quota for the organization") + updateOrganizationCmd.Flags().Int("environment-quota", 0, "Environment quota for the organization") + updateOrganizationCmd.Flags().Int("route-quota", 0, "Route quota for the organization") + + deleteOrgCmd.Flags().StringP("name", "O", "", "Name of the organization to delete") +} diff --git a/cmd/project.go b/cmd/project.go index 25863c1e..8a41a5a8 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -6,7 +6,9 @@ import ( "fmt" l "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" + s "github.com/uselagoon/machinery/api/schema" "os" + "strconv" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -366,6 +368,229 @@ var deleteProjectMetadataByKey = &cobra.Command{ }, } +var addProjectToOrganizationCmd = &cobra.Command{ + Use: "project", + Aliases: []string{"p"}, + Short: "Add a project to an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + gitUrl, err := cmd.Flags().GetString("git-url") + if err != nil { + return err + } + if err := requiredInputCheck("gitUrl", gitUrl); err != nil { + return err + } + productionEnvironment, err := cmd.Flags().GetString("production-environment") + if err != nil { + return err + } + if err := requiredInputCheck("Production Environment", productionEnvironment); err != nil { + return err + } + openshift, err := cmd.Flags().GetUint("openshift") + if err != nil { + return err + } + if err := requiredInputCheck("openshift", strconv.Itoa(int(openshift))); err != nil { + return err + } + standbyProductionEnvironment, err := cmd.Flags().GetString("standby-production-environment") + if err != nil { + return err + } + branches, err := cmd.Flags().GetString("branches") + if err != nil { + return err + } + pullrequests, err := cmd.Flags().GetString("pullrequests") + if err != nil { + return err + } + openshiftProjectPattern, err := cmd.Flags().GetString("openshift-project-pattern") + if err != nil { + return err + } + developmentEnvironmentsLimit, err := cmd.Flags().GetUint("development-environments-limit") + if err != nil { + return err + } + storageCalc, err := cmd.Flags().GetUint("storage-calc") + if err != nil { + return err + } + autoIdle, err := cmd.Flags().GetUint("auto-idle") + if err != nil { + return err + } + subfolder, err := cmd.Flags().GetString("subfolder") + if err != nil { + return err + } + privateKey, err := cmd.Flags().GetString("private-key") + if err != nil { + return err + } + orgOwner, err := cmd.Flags().GetBool("org-owner") + if err != nil { + return err + } + buildImage, err := cmd.Flags().GetString("build-image") + if err != nil { + return err + } + availability, err := cmd.Flags().GetString("availability") + if err != nil { + return err + } + factsUi, err := cmd.Flags().GetUint("facts-ui") + if err != nil { + return err + } + problemsUi, err := cmd.Flags().GetUint("problems-ui") + if err != nil { + return err + } + routerPattern, err := cmd.Flags().GetString("router-pattern") + if err != nil { + return err + } + deploymentsDisabled, err := cmd.Flags().GetUint("deployments-disabled") + if err != nil { + return err + } + ProductionBuildPriority, err := cmd.Flags().GetUint("production-build-priority") + if err != nil { + return err + } + DevelopmentBuildPriority, err := cmd.Flags().GetUint("development-build-priority") + if err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + projectInput := s.AddProjectInput{ + Name: cmdProjectName, + Organization: organization.ID, + AddOrgOwner: orgOwner, + BuildImage: buildImage, + Availability: s.ProjectAvailability(availability), + GitURL: gitUrl, + ProductionEnvironment: productionEnvironment, + StandbyProductionEnvironment: standbyProductionEnvironment, + Branches: branches, + PullRequests: pullrequests, + OpenshiftProjectPattern: openshiftProjectPattern, + Openshift: openshift, + DevelopmentEnvironmentsLimit: developmentEnvironmentsLimit, + StorageCalc: storageCalc, + AutoIdle: autoIdle, + Subfolder: subfolder, + PrivateKey: privateKey, + RouterPattern: routerPattern, + ProblemsUI: problemsUi, + FactsUI: factsUi, + ProductionBuildPriority: ProductionBuildPriority, + DevelopmentBuildPriority: DevelopmentBuildPriority, + DeploymentsDisabled: deploymentsDisabled, + } + project := s.Project{} + err = lc.AddProject(context.TODO(), &projectInput, &project) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Project Name": project.Name, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + +var RemoveProjectFromOrganizationCmd = &cobra.Command{ + Use: "project", + Aliases: []string{"p"}, + Short: "Remove a project from an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + handleError(err) + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + projectInput := s.RemoveProjectFromOrganizationInput{ + Project: project.ID, + Organization: organization.ID, + } + + if yesNo(fmt.Sprintf("You are attempting to remove project '%s' from organization '%s'. This will return the project to a state where it has no groups or notifications associated, are you sure?", cmdProjectName, organization.Name)) { + _, err := l.RemoveProjectFromOrganization(context.TODO(), &projectInput, lc) + handleError(err) + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "Project Name": cmdProjectName, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + } + return nil + }, +} + func init() { updateProjectCmd.Flags().StringVarP(&jsonPatch, "json", "j", "", "JSON string to patch") @@ -420,4 +645,31 @@ func init() { deleteProjectMetadataByKey.Flags().StringP("key", "K", "", "The key name of the metadata value you are querying on") getCmd.AddCommand(getProjectMetadata) + + addProjectToOrganizationCmd.Flags().String("build-image", "", "Build Image for the project") + addProjectToOrganizationCmd.Flags().String("availability", "", "Availability of the project") + addProjectToOrganizationCmd.Flags().String("git-url", "", "GitURL of the project") + addProjectToOrganizationCmd.Flags().String("production-environment", "", "Production Environment for the project") + addProjectToOrganizationCmd.Flags().String("standby-production-environment", "", "Standby Production Environment for the project") + addProjectToOrganizationCmd.Flags().String("subfolder", "", "Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository") + addProjectToOrganizationCmd.Flags().String("private-key", "", "Private key to use for the project") + addProjectToOrganizationCmd.Flags().String("branches", "", "branches") + addProjectToOrganizationCmd.Flags().String("pullrequests", "", "Which Pull Requests should be deployed") + addProjectToOrganizationCmd.Flags().StringP("name", "O", "", "Name of the Organization to add the project to") + addProjectToOrganizationCmd.Flags().String("openshift-project-pattern", "", "Pattern of OpenShift Project/Namespace that should be generated") + addProjectToOrganizationCmd.Flags().String("router-pattern", "", "Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com'") + + addProjectToOrganizationCmd.Flags().Uint("openshift", 0, "Reference to OpenShift Object this Project should be deployed to") + addProjectToOrganizationCmd.Flags().Uint("auto-idle", 0, "Auto idle setting of the project") + addProjectToOrganizationCmd.Flags().Uint("storage-calc", 0, "Should storage for this environment be calculated") + addProjectToOrganizationCmd.Flags().Uint("development-environments-limit", 0, "How many environments can be deployed at one time") + addProjectToOrganizationCmd.Flags().Uint("facts-ui", 0, "Enables the Lagoon insights Facts tab in the UI. Set to 1 to enable, 0 to disable") + addProjectToOrganizationCmd.Flags().Uint("problems-ui", 0, "Enables the Lagoon insights Problems tab in the UI. Set to 1 to enable, 0 to disable") + addProjectToOrganizationCmd.Flags().Uint("deployments-disabled", 0, "Admin only flag for disabling deployments on a project, 1 to disable deployments, 0 to enable") + addProjectToOrganizationCmd.Flags().Uint("production-build-priority", 0, "Set the priority of the production build") + addProjectToOrganizationCmd.Flags().Uint("development-build-priority", 0, "Set the priority of the development build") + + addProjectToOrganizationCmd.Flags().Bool("org-owner", false, "Add the user as an owner of the project") + + RemoveProjectFromOrganizationCmd.Flags().StringP("name", "O", "", "Name of the Organization to remove the project from") } diff --git a/cmd/root.go b/cmd/root.go index 78048555..a98b4109 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -194,6 +194,7 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e rootCmd.AddCommand(importCmd) rootCmd.AddCommand(exportCmd) rootCmd.AddCommand(whoamiCmd) + rootCmd.AddCommand(uploadCmd) } // version/build information command diff --git a/cmd/shared.go b/cmd/shared.go index d878be0e..7af150db 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -1,10 +1,10 @@ package cmd import ( + "fmt" + "github.com/uselagoon/lagoon-cli/pkg/output" "os" "strings" - - "github.com/uselagoon/lagoon-cli/pkg/output" ) // config vars @@ -91,3 +91,31 @@ func fileExists(filename string) bool { func stripNewLines(stripString string) string { return strings.TrimSuffix(stripString, "\n") } + +func nullStrCheck(s string) *string { + if s == "" { + return nil + } + return &s +} + +func nullUintCheck(i uint) *uint { + if i == 0 { + return nil + } + return &i +} + +func nullIntCheck(i int) *int { + if i == 0 { + return nil + } + return &i +} + +func requiredInputCheck(field string, value string) error { + if value == "" || value == "0" { + return fmt.Errorf(fmt.Sprintf("Missing argument: %s is not defined", field)) + } + return nil +} diff --git a/cmd/tasks.go b/cmd/tasks.go index a927f91b..4d291c30 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -6,13 +6,16 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" + "os" + "strings" + "github.com/spf13/cobra" "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" + l "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - "io/ioutil" - "os" ) var getTaskByID = &cobra.Command{ @@ -276,6 +279,65 @@ Path: }, } +var uploadFilesToTask = &cobra.Command{ + Use: "task-files", + Short: "Upload files to a task by its ID", + Long: `Upload files to a task by its ID`, + Aliases: []string{"tf"}, + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + + taskID, err := cmd.Flags().GetInt("id") + if err != nil { + return err + } + if taskID == 0 { + return fmt.Errorf("Missing arguments: ID is not defined") + } + files, err := cmd.Flags().GetStringSlice("file") + if err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + result, err := l.UploadFilesForTask(context.TODO(), taskID, files, lc) + if err != nil { + return err + } + taskFiles := []string{} + for _, f := range result.Files { + taskFiles = append(taskFiles, f.Filename) + } + dataMain := output.Table{ + Header: []string{ + "ID", + "Name", + "Files", + }, + Data: []output.Data{ + { + fmt.Sprintf("%d", result.ID), + returnNonEmptyString(result.Name), + returnNonEmptyString(strings.Join(taskFiles, ",")), + }, + }, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + var ( taskName string invokedTaskName string @@ -285,6 +347,8 @@ var ( ) func init() { + uploadFilesToTask.Flags().IntP("id", "I", 0, "ID of the task") + uploadFilesToTask.Flags().StringSliceP("file", "F", []string{}, "File to upload (add multiple flags to upload multiple files)") invokeDefinedTask.Flags().StringVarP(&invokedTaskName, "name", "N", "", "Name of the task that will be invoked") runCustomTask.Flags().StringVarP(&taskName, "name", "N", "Custom Task", "Name of the task that will show in the UI (default: Custom Task)") runCustomTask.Flags().StringVarP(&taskService, "service", "S", "cli", "Name of the service (cli, nginx, other) that should run the task (default: cli)") diff --git a/cmd/update.go b/cmd/update.go index 68a23ff7..12106614 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -29,4 +29,5 @@ func init() { updateCmd.AddCommand(updateUserCmd) updateCmd.AddCommand(updateDeployTargetConfigCmd) updateCmd.AddCommand(updateDeployTargetCmd) + updateCmd.AddCommand(updateOrganizationCmd) } diff --git a/cmd/upload.go b/cmd/upload.go new file mode 100644 index 00000000..33049ae0 --- /dev/null +++ b/cmd/upload.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var uploadCmd = &cobra.Command{ + Use: "upload", + Aliases: []string{"u"}, + Short: "Upload files to tasks", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + }, +} + +func init() { + uploadCmd.AddCommand(uploadFilesToTask) +} diff --git a/cmd/users.go b/cmd/users.go index 1178213b..c493ad5e 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -1,11 +1,16 @@ package cmd import ( + "context" "encoding/json" "errors" "fmt" + l "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + s "github.com/uselagoon/machinery/api/schema" "io/ioutil" "os" + "strconv" "strings" "github.com/spf13/cobra" @@ -147,22 +152,36 @@ var deleteSSHKeyCmd = &cobra.Command{ Use: "user-sshkey", Aliases: []string{"u"}, Short: "Delete an SSH key from Lagoon", - Run: func(cmd *cobra.Command, args []string) { - if sshKeyName == "" { - fmt.Println("Missing arguments: SSH key name is not defined") - cmd.Help() - os.Exit(1) + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + sshKeyID, err := cmd.Flags().GetUint("id") + if err != nil { + return err } - var customReqResult []byte - var err error - if yesNo(fmt.Sprintf("You are attempting to delete SSH key named '%s', are you sure?", sshKeyName)) { - customReqResult, err = uClient.DeleteSSHKey(sshKeyName) + if sshKeyID == 0 { + fmt.Println("Missing arguments: SSH key ID is not defined") + return nil + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + if yesNo(fmt.Sprintf("You are attempting to delete SSH key ID:'%d', are you sure?", sshKeyID)) { + _, err := l.RemoveSSHKey(context.TODO(), sshKeyID, lc) handleError(err) resultData := output.Result{ - Result: string(customReqResult), + Result: "success", } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -226,23 +245,55 @@ var getUserKeysCmd = &cobra.Command{ Aliases: []string{"us"}, Short: "Get a user's SSH keys", Long: `Get a user's SSH keys. This will only work for users that are part of a group`, - Run: func(cmd *cobra.Command, args []string) { + 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 + } + userEmail, err := cmd.Flags().GetString("email") + if err != nil { + return err + } if userEmail == "" { fmt.Println("Missing arguments: Email address is not defined") - cmd.Help() - os.Exit(1) + return nil } - returnedJSON, err := uClient.ListUserSSHKeys(groupName, strings.ToLower(userEmail), false) - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + userKeys, err := l.GetUserSSHKeysByEmail(context.TODO(), userEmail, lc) handleError(err) - if len(dataMain.Data) == 0 { + if len(userKeys.SSHKeys) == 0 { output.RenderInfo(fmt.Sprintf("No SSH keys for user '%s'", strings.ToLower(userEmail)), outputOptions) - os.Exit(0) + return nil + } + + data := []output.Data{} + for _, userkey := range userKeys.SSHKeys { + data = append(data, []string{ + strconv.Itoa(int(userkey.ID)), + userKeys.Email, + userkey.Name, + string(userkey.KeyType), + userkey.KeyValue, + }) + } + + dataMain := output.Table{ + Header: []string{"ID", "Email", "Name", "Type", "Value"}, + Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -252,18 +303,189 @@ var getAllUserKeysCmd = &cobra.Command{ Aliases: []string{"aus"}, Short: "Get all user SSH keys", Long: `Get all user SSH keys. This will only work for users that are part of a group`, - Run: func(cmd *cobra.Command, args []string) { - returnedJSON, err := uClient.ListUserSSHKeys(groupName, strings.ToLower(userEmail), true) - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) + 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) + groupMembers, err := l.ListAllGroupMembersWithKeys(context.TODO(), groupName, lc) handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo("No SSH keys for any users", outputOptions) - os.Exit(0) + + var userGroups []s.AddSSHKeyInput + for _, group := range *groupMembers { + for _, member := range group.Members { + for _, key := range member.User.SSHKeys { + userGroups = append(userGroups, s.AddSSHKeyInput{SSHKey: key, UserEmail: member.User.Email}) + } + } } + + var data []output.Data + for _, userData := range userGroups { + keyID := strconv.Itoa(int(userData.SSHKey.ID)) + userEmail := returnNonEmptyString(strings.Replace(userData.UserEmail, " ", "_", -1)) + keyName := returnNonEmptyString(strings.Replace(userData.SSHKey.Name, " ", "_", -1)) + keyValue := returnNonEmptyString(strings.Replace(userData.SSHKey.KeyValue, " ", "_", -1)) + keyType := returnNonEmptyString(strings.Replace(string(userData.SSHKey.KeyType), " ", "_", -1)) + data = append(data, []string{ + keyID, + userEmail, + keyName, + keyType, + keyValue, + }) + } + + dataMain := output.Table{ + Header: []string{"ID", "Email", "Name", "Type", "Value"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil + }, +} + +var addUserToOrganizationCmd = &cobra.Command{ + Use: "user", + Aliases: []string{"u"}, + Short: "Add a user to an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + userEmail, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + if err := requiredInputCheck("User email", userEmail); err != nil { + return err + } + owner, err := cmd.Flags().GetBool("owner") + if err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + userInput := s.AddUserToOrganizationInput{ + User: s.UserInput{Email: userEmail}, + Organization: organization.ID, + Owner: owner, + } + + orgUser := s.Organization{} + err = lc.AddUserToOrganization(context.TODO(), &userInput, &orgUser) + handleError(err) + + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "User": userEmail, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + return nil + }, +} + +var RemoveUserFromOrganization = &cobra.Command{ + Use: "user", + Aliases: []string{"u"}, + Short: "Remove a user to an Organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + handleError(err) + + organizationName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Organization name", organizationName); err != nil { + return err + } + userEmail, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + if err := requiredInputCheck("User email", userEmail); err != nil { + return err + } + owner, err := cmd.Flags().GetBool("owner") + if err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + &token, + debug) + organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + handleError(err) + + userInput := s.AddUserToOrganizationInput{ + User: s.UserInput{Email: userEmail}, + Organization: organization.ID, + Owner: owner, + } + + orgUser := s.Organization{} + + if yesNo(fmt.Sprintf("You are attempting to remove user '%s' from organization '%s'. This removes the users ability to view or manage the organizations groups, projects, & notifications, are you sure?", userEmail, organization.Name)) { + err = lc.RemoveUserFromOrganization(context.TODO(), &userInput, &orgUser) + handleError(err) + resultData := output.Result{ + Result: "success", + ResultData: map[string]interface{}{ + "User": userEmail, + "Organization Name": organizationName, + }, + } + output.RenderResult(resultData, outputOptions) + } + return nil }, } @@ -281,12 +503,17 @@ func init() { addUserSSHKeyCmd.Flags().StringVarP(&pubKeyFile, "pubkey", "K", "", "Specify path to the public key to add") addUserSSHKeyCmd.Flags().StringVarP(&pubKeyValue, "keyvalue", "V", "", "Value of the public key to add (ssh-ed25519 AAA..)") deleteUserCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") - deleteSSHKeyCmd.Flags().StringVarP(&sshKeyName, "keyname", "N", "", "Name of the SSH key") + deleteSSHKeyCmd.Flags().Uint("id", 0, "ID of the SSH key") updateUserCmd.Flags().StringVarP(&userFirstName, "firstName", "F", "", "New first name of the user") updateUserCmd.Flags().StringVarP(&userLastName, "lastName", "L", "", "New last name of the user") updateUserCmd.Flags().StringVarP(&userEmail, "email", "E", "", "New email address of the user") updateUserCmd.Flags().StringVarP(¤tUserEmail, "current-email", "C", "", "Current email address of the user") - getUserKeysCmd.Flags().StringVarP(&userEmail, "email", "E", "", "New email address of the user") - getUserKeysCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group to check users in (if not specified, will default to all groups)") - getAllUserKeysCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group to list users in (if not specified, will default to all groups)") + getUserKeysCmd.Flags().StringP("email", "E", "", "New email address of the user") + getAllUserKeysCmd.Flags().StringP("name", "N", "", "Name of the group to list users in (if not specified, will default to all groups)") + addUserToOrganizationCmd.Flags().StringP("name", "O", "", "Name of the organization") + addUserToOrganizationCmd.Flags().StringP("email", "E", "", "Email address of the user") + addUserToOrganizationCmd.Flags().Bool("owner", false, "Set the user as an owner of the organization") + RemoveUserFromOrganization.Flags().StringP("name", "O", "", "Name of the organization") + RemoveUserFromOrganization.Flags().StringP("email", "E", "", "Email address of the user") + RemoveUserFromOrganization.Flags().Bool("owner", false, "Set the user as an owner of the organization") } diff --git a/docs/commands/lagoon.md b/docs/commands/lagoon.md index 7ab9ad66..c1a1cb3f 100644 --- a/docs/commands/lagoon.md +++ b/docs/commands/lagoon.md @@ -45,6 +45,7 @@ lagoon [flags] * [lagoon run](lagoon_run.md) - Run a task against an environment * [lagoon ssh](lagoon_ssh.md) - Display the SSH command to access a specific environment in a project * [lagoon update](lagoon_update.md) - Update a resource +* [lagoon upload](lagoon_upload.md) - Upload files to tasks * [lagoon version](lagoon_version.md) - Version information * [lagoon web](lagoon_web.md) - Launch the web user interface * [lagoon whoami](lagoon_whoami.md) - Whoami will return your user information for lagoon diff --git a/docs/commands/lagoon_add.md b/docs/commands/lagoon_add.md index e54917c5..5a97546a 100644 --- a/docs/commands/lagoon_add.md +++ b/docs/commands/lagoon_add.md @@ -36,6 +36,7 @@ Add a project, or add notifications and variables to projects or environments * [lagoon add deploytarget-config](lagoon_add_deploytarget-config.md) - Add deploytarget config to a project * [lagoon add group](lagoon_add_group.md) - Add a group to lagoon * [lagoon add notification](lagoon_add_notification.md) - Add notifications or add notifications to projects +* [lagoon add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization * [lagoon add project](lagoon_add_project.md) - Add a new project to Lagoon * [lagoon add project-group](lagoon_add_project-group.md) - Add a project to a group in lagoon * [lagoon add user](lagoon_add_user.md) - Add a user to lagoon diff --git a/docs/commands/lagoon_add_organization.md b/docs/commands/lagoon_add_organization.md new file mode 100644 index 00000000..efcb823e --- /dev/null +++ b/docs/commands/lagoon_add_organization.md @@ -0,0 +1,40 @@ +## lagoon add organization + +Add an organization, or add a group/project to an organization + +### Synopsis + +Add an organization, or add a group/project to an organization + +### Options + +``` + -h, --help help for organization +``` + +### 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 add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments +* [lagoon add organization deploytarget](lagoon_add_organization_deploytarget.md) - Add a deploy target to an Organization +* [lagoon add organization group](lagoon_add_organization_group.md) - Add a group to an Organization +* [lagoon add organization organization](lagoon_add_organization_organization.md) - Add a new organization to Lagoon +* [lagoon add organization project](lagoon_add_organization_project.md) - Add a project to an Organization +* [lagoon add organization user](lagoon_add_organization_user.md) - Add a user to an Organization + diff --git a/docs/commands/lagoon_add_organization_deploytarget.md b/docs/commands/lagoon_add_organization_deploytarget.md new file mode 100644 index 00000000..d618390f --- /dev/null +++ b/docs/commands/lagoon_add_organization_deploytarget.md @@ -0,0 +1,41 @@ +## lagoon add organization deploytarget + +Add a deploy target to an Organization + +### Synopsis + +Add a deploy target to an Organization + +``` +lagoon add organization deploytarget [flags] +``` + +### Options + +``` + -D, --deploy-target uint ID of DeployTarget + -h, --help help for deploytarget + -O, --name string Name of Organization +``` + +### 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 add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_add_organization_group.md b/docs/commands/lagoon_add_organization_group.md new file mode 100644 index 00000000..2a929f9e --- /dev/null +++ b/docs/commands/lagoon_add_organization_group.md @@ -0,0 +1,42 @@ +## lagoon add organization group + +Add a group to an Organization + +### Synopsis + +Add a group to an Organization + +``` +lagoon add organization group [flags] +``` + +### Options + +``` + -G, --group string Name of the group + -h, --help help for group + -O, --name string Name of the organization + --org-owner Flag to add the user to the group as an owner +``` + +### 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 add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_add_organization_organization.md b/docs/commands/lagoon_add_organization_organization.md new file mode 100644 index 00000000..a1b3af72 --- /dev/null +++ b/docs/commands/lagoon_add_organization_organization.md @@ -0,0 +1,47 @@ +## lagoon add organization organization + +Add a new organization to Lagoon + +### Synopsis + +Add a new organization to Lagoon + +``` +lagoon add organization organization [flags] +``` + +### Options + +``` + --description string Description of the organization + --environment-quota int Environment quota for the organization + --friendly-name string Friendly name of the organization + --group-quota int Group quota for the organization + -h, --help help for organization + -O, --name string Name of the organization + --notification-quota int Notification quota for the organization + --project-quota int Project quota for the organization + --route-quota int Route quota for the organization +``` + +### 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 add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_add_organization_project.md b/docs/commands/lagoon_add_organization_project.md new file mode 100644 index 00000000..0e86ae21 --- /dev/null +++ b/docs/commands/lagoon_add_organization_project.md @@ -0,0 +1,61 @@ +## lagoon add organization project + +Add a project to an Organization + +### Synopsis + +Add a project to an Organization + +``` +lagoon add organization project [flags] +``` + +### Options + +``` + --auto-idle uint Auto idle setting of the project + --availability string Availability of the project + --branches string branches + --build-image string Build Image for the project + --deployments-disabled uint Admin only flag for disabling deployments on a project, 1 to disable deployments, 0 to enable + --development-build-priority uint Set the priority of the development build + --development-environments-limit uint How many environments can be deployed at one time + --facts-ui uint Enables the Lagoon insights Facts tab in the UI. Set to 1 to enable, 0 to disable + --git-url string GitURL of the project + -h, --help help for project + -O, --name string Name of the Organization to add the project to + --openshift uint Reference to OpenShift Object this Project should be deployed to + --openshift-project-pattern string Pattern of OpenShift Project/Namespace that should be generated + --org-owner Add the user as an owner of the project + --private-key string Private key to use for the project + --problems-ui uint Enables the Lagoon insights Problems tab in the UI. Set to 1 to enable, 0 to disable + --production-build-priority uint Set the priority of the production build + --production-environment string Production Environment for the project + --pullrequests string Which Pull Requests should be deployed + --router-pattern string Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com' + --standby-production-environment string Standby Production Environment for the project + --storage-calc uint Should storage for this environment be calculated + --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository +``` + +### 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 add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_add_organization_user.md b/docs/commands/lagoon_add_organization_user.md new file mode 100644 index 00000000..411879fb --- /dev/null +++ b/docs/commands/lagoon_add_organization_user.md @@ -0,0 +1,42 @@ +## lagoon add organization user + +Add a user to an Organization + +### Synopsis + +Add a user to an Organization + +``` +lagoon add organization user [flags] +``` + +### Options + +``` + -E, --email string Email address of the user + -h, --help help for user + -O, --name string Name of the organization + --owner Set the user as an owner of the organization +``` + +### 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 add organization](lagoon_add_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_delete.md b/docs/commands/lagoon_delete.md index b8b4e8e6..b163a592 100644 --- a/docs/commands/lagoon_delete.md +++ b/docs/commands/lagoon_delete.md @@ -37,6 +37,7 @@ Delete a project, or delete notifications and variables from projects or environ * [lagoon delete environment](lagoon_delete_environment.md) - Delete an environment * [lagoon delete group](lagoon_delete_group.md) - Delete a group from lagoon * [lagoon delete notification](lagoon_delete_notification.md) - Delete notifications or delete notifications from projects +* [lagoon delete organization](lagoon_delete_organization.md) - Add an organization, or add a group/project to an organization * [lagoon delete project](lagoon_delete_project.md) - Delete a project * [lagoon delete project-group](lagoon_delete_project-group.md) - Delete a project from a group in lagoon * [lagoon delete project-metadata](lagoon_delete_project-metadata.md) - Delete a key from a projects metadata diff --git a/docs/commands/lagoon_delete_organization.md b/docs/commands/lagoon_delete_organization.md new file mode 100644 index 00000000..733b9640 --- /dev/null +++ b/docs/commands/lagoon_delete_organization.md @@ -0,0 +1,39 @@ +## lagoon delete organization + +Add an organization, or add a group/project to an organization + +### Synopsis + +Add an organization, or add a group/project to an organization + +### Options + +``` + -h, --help help for organization +``` + +### 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 delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments +* [lagoon delete organization deploytarget](lagoon_delete_organization_deploytarget.md) - Remove a deploy target from an Organization +* [lagoon delete organization organization](lagoon_delete_organization_organization.md) - Delete an organization +* [lagoon delete organization project](lagoon_delete_organization_project.md) - Remove a project from an Organization +* [lagoon delete organization user](lagoon_delete_organization_user.md) - Remove a user to an Organization + diff --git a/docs/commands/lagoon_delete_organization_deploytarget.md b/docs/commands/lagoon_delete_organization_deploytarget.md new file mode 100644 index 00000000..173873c6 --- /dev/null +++ b/docs/commands/lagoon_delete_organization_deploytarget.md @@ -0,0 +1,41 @@ +## lagoon delete organization deploytarget + +Remove a deploy target from an Organization + +### Synopsis + +Remove a deploy target from an Organization + +``` +lagoon delete organization deploytarget [flags] +``` + +### Options + +``` + -D, --deploy-target uint ID of DeployTarget + -h, --help help for deploytarget + -O, --name string Name of Organization +``` + +### 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 delete organization](lagoon_delete_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_delete_organization_organization.md b/docs/commands/lagoon_delete_organization_organization.md new file mode 100644 index 00000000..2c0cc29f --- /dev/null +++ b/docs/commands/lagoon_delete_organization_organization.md @@ -0,0 +1,40 @@ +## lagoon delete organization organization + +Delete an organization + +### Synopsis + +Delete an organization + +``` +lagoon delete organization organization [flags] +``` + +### Options + +``` + -h, --help help for organization + -O, --name string Name of the organization to delete +``` + +### 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 delete organization](lagoon_delete_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_delete_organization_project.md b/docs/commands/lagoon_delete_organization_project.md new file mode 100644 index 00000000..5f814ff1 --- /dev/null +++ b/docs/commands/lagoon_delete_organization_project.md @@ -0,0 +1,40 @@ +## lagoon delete organization project + +Remove a project from an Organization + +### Synopsis + +Remove a project from an Organization + +``` +lagoon delete organization project [flags] +``` + +### Options + +``` + -h, --help help for project + -O, --name string Name of the Organization to remove the project from +``` + +### 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 delete organization](lagoon_delete_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_delete_organization_user.md b/docs/commands/lagoon_delete_organization_user.md new file mode 100644 index 00000000..7b542f1d --- /dev/null +++ b/docs/commands/lagoon_delete_organization_user.md @@ -0,0 +1,42 @@ +## lagoon delete organization user + +Remove a user to an Organization + +### Synopsis + +Remove a user to an Organization + +``` +lagoon delete organization user [flags] +``` + +### Options + +``` + -E, --email string Email address of the user + -h, --help help for user + -O, --name string Name of the organization + --owner Set the user as an owner of the organization +``` + +### 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 delete organization](lagoon_delete_organization.md) - Add an organization, or add a group/project to an organization + diff --git a/docs/commands/lagoon_delete_user-sshkey.md b/docs/commands/lagoon_delete_user-sshkey.md index cb7184e9..3c08eaaf 100644 --- a/docs/commands/lagoon_delete_user-sshkey.md +++ b/docs/commands/lagoon_delete_user-sshkey.md @@ -13,8 +13,8 @@ lagoon delete user-sshkey [flags] ### Options ``` - -h, --help help for user-sshkey - -N, --keyname string Name of the SSH key + -h, --help help for user-sshkey + --id uint ID of the SSH key ``` ### Options inherited from parent commands diff --git a/docs/commands/lagoon_get.md b/docs/commands/lagoon_get.md index f6ceda5b..77b6c4e4 100644 --- a/docs/commands/lagoon_get.md +++ b/docs/commands/lagoon_get.md @@ -34,8 +34,9 @@ Get info on a resource * [lagoon](lagoon.md) - Command line integration for Lagoon * [lagoon get all-user-sshkeys](lagoon_get_all-user-sshkeys.md) - Get all user SSH keys * [lagoon get backup](lagoon_get_backup.md) - Get a backup download link -* [lagoon get deployment](lagoon_get_deployment.md) - Get a build log by remote id +* [lagoon get deployment](lagoon_get_deployment.md) - Get a deployment by name * [lagoon get environment](lagoon_get_environment.md) - Get details about an environment +* [lagoon get organization](lagoon_get_organization.md) - Get details about an organization * [lagoon get project](lagoon_get_project.md) - Get details about a project * [lagoon get project-key](lagoon_get_project-key.md) - Get a projects public key * [lagoon get project-metadata](lagoon_get_project-metadata.md) - Get all metadata for a project diff --git a/docs/commands/lagoon_get_deployment.md b/docs/commands/lagoon_get_deployment.md index e98efa59..5bdbcc47 100644 --- a/docs/commands/lagoon_get_deployment.md +++ b/docs/commands/lagoon_get_deployment.md @@ -1,10 +1,11 @@ ## lagoon get deployment -Get a build log by remote id +Get a deployment by name ### Synopsis -Get a build log by remote id +Get a deployment by name +This returns information about a deployment, the logs of this build can also be retrieved ``` lagoon get deployment [flags] @@ -13,8 +14,9 @@ lagoon get deployment [flags] ### Options ``` - -h, --help help for deployment - -R, --remoteid string The remote ID of the deployment + -h, --help help for deployment + -L, --logs Show the build logs if available + -N, --name string The name of the deployment (eg, lagoon-build-abcdef) ``` ### Options inherited from parent commands diff --git a/docs/commands/lagoon_get_organization.md b/docs/commands/lagoon_get_organization.md new file mode 100644 index 00000000..d7e3438f --- /dev/null +++ b/docs/commands/lagoon_get_organization.md @@ -0,0 +1,40 @@ +## lagoon get organization + +Get details about an organization + +### Synopsis + +Get details about an organization + +``` +lagoon get organization [flags] +``` + +### Options + +``` + -h, --help help for organization + -O, --name string Name of the organization +``` + +### 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 get](lagoon_get.md) - Get info on a resource + diff --git a/docs/commands/lagoon_get_user-sshkeys.md b/docs/commands/lagoon_get_user-sshkeys.md index dd396691..c38f2c3a 100644 --- a/docs/commands/lagoon_get_user-sshkeys.md +++ b/docs/commands/lagoon_get_user-sshkeys.md @@ -15,7 +15,6 @@ lagoon get user-sshkeys [flags] ``` -E, --email string New email address of the user -h, --help help for user-sshkeys - -N, --name string Name of the group to check users in (if not specified, will default to all groups) ``` ### Options inherited from parent commands diff --git a/docs/commands/lagoon_list.md b/docs/commands/lagoon_list.md index e4e790ee..28dc7f04 100644 --- a/docs/commands/lagoon_list.md +++ b/docs/commands/lagoon_list.md @@ -44,6 +44,8 @@ List projects, environments, deployments, variables or notifications * [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 +* [lagoon list organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users +* [lagoon list project-groups](lagoon_list_project-groups.md) - List groups in a project (alias: pg) * [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) diff --git a/docs/commands/lagoon_list_organization.md b/docs/commands/lagoon_list_organization.md new file mode 100644 index 00000000..0142cc33 --- /dev/null +++ b/docs/commands/lagoon_list_organization.md @@ -0,0 +1,40 @@ +## lagoon list organization + +List all organizations projects, groups, deploy targets or users + +### Synopsis + +List all organizations projects, groups, deploy targets or users + +### Options + +``` + -h, --help help for organization +``` + +### 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 +* [lagoon list organization deploytargets](lagoon_list_organization_deploytargets.md) - List deploy targets in an organization +* [lagoon list organization groups](lagoon_list_organization_groups.md) - List groups in an organization +* [lagoon list organization organizations](lagoon_list_organization_organizations.md) - List all organizations +* [lagoon list organization projects](lagoon_list_organization_projects.md) - List projects in an organization +* [lagoon list organization users](lagoon_list_organization_users.md) - List users in an organization + diff --git a/docs/commands/lagoon_list_organization_deploytargets.md b/docs/commands/lagoon_list_organization_deploytargets.md new file mode 100644 index 00000000..80518ab2 --- /dev/null +++ b/docs/commands/lagoon_list_organization_deploytargets.md @@ -0,0 +1,41 @@ +## lagoon list organization deploytargets + +List deploy targets in an organization + +### Synopsis + +List deploy targets in an organization + +``` +lagoon list organization deploytargets [flags] +``` + +### Options + +``` + -h, --help help for deploytargets + --id uint ID of the organization to list associated deploy targets for + -O, --name string Name of the organization to list associated deploy targets for +``` + +### 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 organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users + diff --git a/docs/commands/lagoon_list_organization_groups.md b/docs/commands/lagoon_list_organization_groups.md new file mode 100644 index 00000000..af0c6d1e --- /dev/null +++ b/docs/commands/lagoon_list_organization_groups.md @@ -0,0 +1,40 @@ +## lagoon list organization groups + +List groups in an organization + +### Synopsis + +List groups in an organization + +``` +lagoon list organization groups [flags] +``` + +### Options + +``` + -h, --help help for groups + -O, --name string Name of the organization to list associated groups for +``` + +### 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 organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users + diff --git a/docs/commands/lagoon_list_organization_organizations.md b/docs/commands/lagoon_list_organization_organizations.md new file mode 100644 index 00000000..09ff1c21 --- /dev/null +++ b/docs/commands/lagoon_list_organization_organizations.md @@ -0,0 +1,39 @@ +## lagoon list organization organizations + +List all organizations + +### Synopsis + +List all organizations + +``` +lagoon list organization organizations [flags] +``` + +### Options + +``` + -h, --help help for organizations +``` + +### 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 organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users + diff --git a/docs/commands/lagoon_list_organization_projects.md b/docs/commands/lagoon_list_organization_projects.md new file mode 100644 index 00000000..3127a163 --- /dev/null +++ b/docs/commands/lagoon_list_organization_projects.md @@ -0,0 +1,40 @@ +## lagoon list organization projects + +List projects in an organization + +### Synopsis + +List projects in an organization + +``` +lagoon list organization projects [flags] +``` + +### Options + +``` + -h, --help help for projects + -O, --name string Name of the organization to list associated projects for +``` + +### 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 organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users + diff --git a/docs/commands/lagoon_list_organization_users.md b/docs/commands/lagoon_list_organization_users.md new file mode 100644 index 00000000..d3cbfcdf --- /dev/null +++ b/docs/commands/lagoon_list_organization_users.md @@ -0,0 +1,40 @@ +## lagoon list organization users + +List users in an organization + +### Synopsis + +List users in an organization + +``` +lagoon list organization users [flags] +``` + +### Options + +``` + -h, --help help for users + -O, --name string Name of the organization to list associated users for +``` + +### 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 organization](lagoon_list_organization.md) - List all organizations projects, groups, deploy targets or users + diff --git a/docs/commands/lagoon_list_project-groups.md b/docs/commands/lagoon_list_project-groups.md new file mode 100644 index 00000000..9bfb2d13 --- /dev/null +++ b/docs/commands/lagoon_list_project-groups.md @@ -0,0 +1,39 @@ +## lagoon list project-groups + +List groups in a project (alias: pg) + +### Synopsis + +List groups in a project (alias: pg) + +``` +lagoon list project-groups [flags] +``` + +### Options + +``` + -h, --help help for project-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/docs/commands/lagoon_list_users.md b/docs/commands/lagoon_list_users.md index 7a22d8d7..7988ae11 100644 --- a/docs/commands/lagoon_list_users.md +++ b/docs/commands/lagoon_list_users.md @@ -36,5 +36,5 @@ lagoon list users [flags] ### SEE ALSO -* [lagoon list](lagoon_list.md) - List projects, deployments, variables or notifications +* [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications diff --git a/docs/commands/lagoon_update.md b/docs/commands/lagoon_update.md index 0421e622..2fb7cd12 100644 --- a/docs/commands/lagoon_update.md +++ b/docs/commands/lagoon_update.md @@ -36,6 +36,7 @@ Update a resource * [lagoon update deploytarget-config](lagoon_update_deploytarget-config.md) - Update a deploytarget config * [lagoon update environment](lagoon_update_environment.md) - Update an environment * [lagoon update notification](lagoon_update_notification.md) - List all notifications or notifications on projects +* [lagoon update organization](lagoon_update_organization.md) - Update an organization * [lagoon update project](lagoon_update_project.md) - Update a project * [lagoon update project-metadata](lagoon_update_project-metadata.md) - Update a projects metadata with a given key or key:value * [lagoon update user](lagoon_update_user.md) - Update a user in Lagoon diff --git a/docs/commands/lagoon_update_organization.md b/docs/commands/lagoon_update_organization.md new file mode 100644 index 00000000..4c64e34e --- /dev/null +++ b/docs/commands/lagoon_update_organization.md @@ -0,0 +1,47 @@ +## lagoon update organization + +Update an organization + +### Synopsis + +Update an organization + +``` +lagoon update organization [flags] +``` + +### Options + +``` + --description string Description of the organization + --environment-quota int Environment quota for the organization + --friendly-name string Friendly name of the organization + --group-quota int Group quota for the organization + -h, --help help for organization + -O, --name string Name of the organization to update + --notification-quota int Notification quota for the organization + --project-quota int Project quota for the organization + --route-quota int Route quota for the organization +``` + +### 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 update](lagoon_update.md) - Update a resource + diff --git a/docs/commands/lagoon_upload.md b/docs/commands/lagoon_upload.md new file mode 100644 index 00000000..a2b43843 --- /dev/null +++ b/docs/commands/lagoon_upload.md @@ -0,0 +1,36 @@ +## lagoon upload + +Upload files to tasks + +### Synopsis + +Upload files to tasks + +### Options + +``` + -h, --help help for upload +``` + +### 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](lagoon.md) - Command line integration for Lagoon +* [lagoon upload task-files](lagoon_upload_task-files.md) - Upload files to a task by its ID + diff --git a/docs/commands/lagoon_upload_task-files.md b/docs/commands/lagoon_upload_task-files.md new file mode 100644 index 00000000..453f250f --- /dev/null +++ b/docs/commands/lagoon_upload_task-files.md @@ -0,0 +1,41 @@ +## lagoon upload task-files + +Upload files to a task by its ID + +### Synopsis + +Upload files to a task by its ID + +``` +lagoon upload task-files [flags] +``` + +### Options + +``` + -F, --file strings File to upload (add multiple flags to upload multiple files) + -h, --help help for task-files + -I, --id int ID of the task +``` + +### 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 upload](lagoon_upload.md) - Upload files to tasks + diff --git a/go.mod b/go.mod index da24df75..e3ab3077 100644 --- a/go.mod +++ b/go.mod @@ -4,32 +4,32 @@ go 1.16 require ( github.com/Masterminds/semver v1.4.2 + github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/golang/mock v1.6.0 github.com/google/go-github v0.0.0-20180716180158-c0b63e2f9bb1 + github.com/google/go-querystring v1.0.0 // indirect github.com/google/uuid v1.3.0 + github.com/guregu/null v4.0.0+incompatible github.com/hashicorp/go-version v1.6.0 github.com/integralist/go-findroot v0.0.0-20160518114804-ac90681525dc github.com/logrusorgru/aurora v0.0.0-20191017060258-dc85c304c434 github.com/machinebox/graphql v0.2.3-0.20181106130121-3a9253180225 github.com/manifoldco/promptui v0.3.2 + // workaround for https://github.com/manifoldco/promptui/issues/98 + github.com/nicksnyder/go-i18n v1.10.1 // indirect github.com/olekukonko/tablewriter v0.0.4 github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.3 - github.com/stretchr/testify v1.2.2 + github.com/stretchr/testify v1.8.2 + 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 ) require ( - github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect - github.com/google/go-querystring v1.0.0 // indirect - github.com/guregu/null v4.0.0+incompatible - // workaround for https://github.com/manifoldco/promptui/issues/98 - github.com/nicksnyder/go-i18n v1.10.1 // indirect - github.com/uselagoon/machinery v0.0.13 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 // indirect @@ -38,9 +38,4 @@ require ( // use this version for fixes to formatting of end header replace github.com/olekukonko/tablewriter => github.com/shreddedbacon/tablewriter v0.0.2-0.20200114082015-d810c4a558bf -// replace github.com/machinebox/graphql => ../../shreddedbacon/graphql - -// replace github.com/olekukonko/tablewriter => ../../shreddedbacon/tablewriter - -// replace github.com/uselagoon/machinery => ../machinery -replace github.com/uselagoon/machinery v0.0.13 => github.com/uselagoon/machinery v0.0.0-20231205012931-58a4ccde55f9 +//replace github.com/uselagoon/machinery => ../machinery diff --git a/go.sum b/go.sum index c99e5e72..b43ef6e6 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,7 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= @@ -99,13 +100,19 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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.0-20231205012931-58a4ccde55f9 h1:PxXlTj6IPuaGIdnAeBIupq2V+HVFCh8fQs0euke/ZJY= -github.com/uselagoon/machinery v0.0.0-20231205012931-58a4ccde55f9/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= @@ -158,5 +165,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/pkg/lagoon/users/main.go b/pkg/lagoon/users/main.go index 4afa8fb6..39d40039 100644 --- a/pkg/lagoon/users/main.go +++ b/pkg/lagoon/users/main.go @@ -23,10 +23,8 @@ type Client interface { ListUsers(string) ([]byte, error) AddUser(api.User) ([]byte, error) AddSSHKeyToUser(api.User, api.SSHKey) ([]byte, error) - DeleteSSHKey(string) ([]byte, error) DeleteUser(api.User) ([]byte, error) ModifyUser(api.User, api.User) ([]byte, error) - ListUserSSHKeys(string, string, bool) ([]byte, error) ListGroups(string) ([]byte, error) ListGroupProjects(string, bool) ([]byte, error) } diff --git a/pkg/lagoon/users/users.go b/pkg/lagoon/users/users.go index c4c15897..1cf3ea5a 100644 --- a/pkg/lagoon/users/users.go +++ b/pkg/lagoon/users/users.go @@ -61,24 +61,6 @@ func (u *Users) AddSSHKeyToUser(user api.User, sshKey api.SSHKey) ([]byte, error return returnResult, nil } -// DeleteSSHKey function -func (u *Users) DeleteSSHKey(keyName string) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation deleteSshKey ($keyname: String!) { - deleteSshKey(input:{name: $keyname}) - }`, - Variables: map[string]interface{}{ - "keyname": keyName, - }, - MappedResult: "deleteSshKey", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - // DeleteUser function func (u *Users) DeleteUser(user api.User) ([]byte, error) { customReq := api.CustomRequest{ @@ -212,58 +194,6 @@ func processUserList(listUsers []byte) ([]byte, error) { return json.Marshal(dataMain) } -// ListUserSSHKeys function -func (u *Users) ListUserSSHKeys(groupName string, email string, allUsers bool) ([]byte, error) { - //@TODO: once individual user interaction comes in, this will need to be adjusted - customReq := api.CustomRequest{ - Query: `query allGroups ($name: String) { - allGroups (name: $name) { - name - id - members{ - user{ - id - email - firstName - lastName - sshKeys{ - name - keyType - keyValue - } - } - role - } - } - }`, - Variables: map[string]interface{}{ - "name": groupName, - }, - MappedResult: "allGroups", - } - listUsers, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - returnedKeys, err := processReturnedUserKeysList(listUsers) - if err != nil { - return []byte(""), err - } - var returnResult []byte - if allUsers { - returnResult, err = processAllUserKeysList(returnedKeys) - if err != nil { - return []byte(""), err - } - } else { - returnResult, err = processUserKeysList(returnedKeys, email) - if err != nil { - return []byte(""), err - } - } - return returnResult, nil -} - func processReturnedUserKeysList(listUsers []byte) ([]ExtendedSSHKey, error) { var groupMembers GroupMembers userDataStep1 := []ExtendedSSHKey{}