diff --git a/cmd/deploy.go b/cmd/deploy.go index fdf1868d..c8b771e4 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -3,11 +3,13 @@ package cmd import ( "context" "fmt" + "strconv" + + lclient "github.com/uselagoon/machinery/api/lagoon/client" "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/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/schema" ) var deployCmd = &cobra.Command{ @@ -43,8 +45,8 @@ use 'lagoon deploy latest' instead`, if err != nil { return err } - if cmdProjectName == "" || branch == "" { - return fmt.Errorf("missing arguments: Project name or branch name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Branch name", branch); err != nil { + return err } buildVarStrings, err := cmd.Flags().GetStringArray("buildvar") @@ -58,11 +60,12 @@ use 'lagoon deploy latest' instead`, if yesNo(fmt.Sprintf("You are attempting to deploy branch '%s' for project '%s', are you sure?", branch, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) depBranch := &schema.DeployEnvironmentBranchInput{ Branch: branch, @@ -108,8 +111,8 @@ var deployPromoteCmd = &cobra.Command{ if err != nil { return err } - if cmdProjectName == "" || sourceEnvironment == "" || destinationEnvironment == "" { - return fmt.Errorf("missing arguments: Project name, source environment, or destination environment is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Source environment", sourceEnvironment, "Destination environment", destinationEnvironment); err != nil { + return err } buildVarStrings, err := cmd.Flags().GetStringArray("buildvar") @@ -123,11 +126,12 @@ var deployPromoteCmd = &cobra.Command{ if yesNo(fmt.Sprintf("You are attempting to promote environment '%s' to '%s' for project '%s', are you sure?", sourceEnvironment, destinationEnvironment, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeployPromote(context.TODO(), &schema.DeployEnvironmentPromoteInput{ SourceEnvironment: sourceEnvironment, @@ -170,21 +174,22 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo if err != nil { return err } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } buildVarMap, err := buildVarsToMap(buildVarStrings) if err != nil { return err } - if cmdProjectName == "" || cmdProjectEnvironment == "" { - return fmt.Errorf("missing arguments: Project name or environment name is not defined") - } if yesNo(fmt.Sprintf("You are attempting to deploy the latest environment '%s' for project '%s', are you sure?", cmdProjectEnvironment, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeployLatest(context.TODO(), &schema.DeployEnvironmentLatestInput{ Environment: schema.EnvironmentInput{ @@ -244,9 +249,8 @@ This pullrequest may not already exist as an environment in lagoon.`, if err != nil { return err } - if cmdProjectName == "" || prTitle == "" || prNumber == 0 || baseBranchName == "" || - baseBranchRef == "" || headBranchName == "" || headBranchRef == "" { - return fmt.Errorf("missing arguments: Project name, title, number, baseBranchName, baseBranchRef, headBranchName, or headBranchRef is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Pullrequest title", prTitle, "Pullrequest number", strconv.Itoa(int(prNumber)), "baseBranchName", baseBranchName, "baseBranchRef", baseBranchRef, "headBranchName", headBranchName, "headBranchRef", headBranchRef); err != nil { + return err } buildVarStrings, err := cmd.Flags().GetStringArray("buildvar") if err != nil { @@ -263,11 +267,12 @@ This pullrequest may not already exist as an environment in lagoon.`, } if yesNo(fmt.Sprintf("You are attempting to deploy pull request '%v' for project '%s', are you sure?", prNumber, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeployPullRequest(context.TODO(), &schema.DeployEnvironmentPullrequestInput{ diff --git a/cmd/deploytarget.go b/cmd/deploytarget.go index 20867cdb..b4f9d27e 100644 --- a/cmd/deploytarget.go +++ b/cmd/deploytarget.go @@ -6,13 +6,10 @@ import ( "strconv" "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" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" ) var addDeployTargetCmd = &cobra.Command{ @@ -65,14 +62,8 @@ var addDeployTargetCmd = &cobra.Command{ return err } - if name == "" { - return fmt.Errorf("missing arguments: name is not defined") - } - if token == "" { - return fmt.Errorf("missing arguments: token is not defined") - } - if consoleURL == "" { - return fmt.Errorf("missing arguments: console-url is not defined") + if err := requiredInputCheck("Name", name, "Token", token, "Console-url", consoleURL); err != nil { + return err } addDeployTarget := &schema.AddDeployTargetInput{ @@ -96,20 +87,21 @@ var addDeployTargetCmd = &cobra.Command{ } debug, err := cmd.Flags().GetBool("debug") if err != nil { - handleError(err) + return err } current := lagoonCLIConfig.Current - lc := client.New( + lagoonToken := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &lagoonToken, debug) if yesNo(fmt.Sprintf("You are attempting to add '%s' DeployTarget, are you sure?", addDeployTarget.Name)) { addDeployTargetResponse, err := lagoon.AddDeployTarget(context.TODO(), addDeployTarget, lc) if err != nil { - handleError(err) + return err } data := []output.Data{} @@ -208,16 +200,22 @@ var updateDeployTargetCmd = &cobra.Command{ debug, err := cmd.Flags().GetBool("debug") if err != nil { - handleError(err) + return err } + + if err := requiredInputCheck("Deploytarget ID", strconv.Itoa(int(id))); err != nil { + return err + } + current := lagoonCLIConfig.Current - lc := client.New( + lagoonToken := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, - debug, - ) + lagoonCLIConfig.Lagoons[current].Version, + &lagoonToken, + debug) + updateDeployTarget := &schema.UpdateDeployTargetInput{ AddDeployTargetInput: schema.AddDeployTargetInput{ ID: id, @@ -235,7 +233,7 @@ var updateDeployTargetCmd = &cobra.Command{ if yesNo(fmt.Sprintf("You are attempting to update '%d' DeployTarget, are you sure?", updateDeployTarget.ID)) { updateDeployTargetResponse, err := lagoon.UpdateDeployTarget(context.TODO(), updateDeployTarget, lc) if err != nil { - handleError(err) + return err } data := []output.Data{} @@ -293,16 +291,21 @@ var deleteDeployTargetCmd = &cobra.Command{ debug, err := cmd.Flags().GetBool("debug") if err != nil { - handleError(err) + return err + } + + if err := requiredInputCheck("Deploytarget name", name); err != nil { + return err } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, - debug, - ) + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) deleteDeployTarget := &schema.DeleteDeployTargetInput{ Name: name, @@ -310,10 +313,9 @@ var deleteDeployTargetCmd = &cobra.Command{ if yesNo(fmt.Sprintf("You are attempting to delete DeployTarget '%s', are you sure?", deleteDeployTarget.Name)) { deleteDeployTargetResponse, err := lagoon.DeleteDeployTarget(context.TODO(), deleteDeployTarget, lc) if err != nil { - handleError(err) + return err } - handleError(err) resultData := output.Result{ Result: deleteDeployTargetResponse.DeleteDeployTarget, } @@ -347,7 +349,6 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ if err := requiredInputCheck("Organization name", organizationName, "Deploy Target", strconv.Itoa(int(deploytarget))); err != nil { return err } - current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token lc := lclient.New( @@ -357,7 +358,7 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -365,15 +366,16 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } - deployTargetInput := s.AddDeployTargetToOrganizationInput{ + deployTargetInput := schema.AddDeployTargetToOrganizationInput{ DeployTarget: deploytarget, Organization: organization.ID, } - deployTargetResponse, err := l.AddDeployTargetToOrganization(context.TODO(), &deployTargetInput, lc) + deployTargetResponse, err := lagoon.AddDeployTargetToOrganization(context.TODO(), &deployTargetInput, lc) if err != nil { return err } + resultData := output.Result{ Result: "success", ResultData: map[string]interface{}{ @@ -420,7 +422,7 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -428,13 +430,13 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } - deployTargetInput := s.RemoveDeployTargetFromOrganizationInput{ + deployTargetInput := schema.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) + _, err := lagoon.RemoveDeployTargetFromOrganization(context.TODO(), &deployTargetInput, lc) if err != nil { return err } diff --git a/cmd/deploytargetconfig.go b/cmd/deploytargetconfig.go index 2287b60c..cb4465f3 100644 --- a/cmd/deploytargetconfig.go +++ b/cmd/deploytargetconfig.go @@ -4,14 +4,13 @@ import ( "context" "fmt" - l "github.com/uselagoon/machinery/api/lagoon" + "strconv" + + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "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" ) @@ -45,18 +44,10 @@ var addDeployTargetConfigCmd = &cobra.Command{ return err } - if cmdProjectName == "" { - return fmt.Errorf("missing arguments: project is a required flag") - } - if deploytarget == 0 { - return fmt.Errorf("missing arguments: deploytarget id is a required flag") - } - if pullrequests == "" { - return fmt.Errorf("missing arguments: pullrequests is a required flag") - } - if branches == "" { - return fmt.Errorf("missing arguments: branches is a required flag") + if err := requiredInputCheck("Project name", cmdProjectName, "Deploytarget", strconv.Itoa(int(deploytarget)), "Pullrequests", pullrequests, "Branches", branches); err != nil { + return err } + current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token lc := lclient.New( @@ -65,12 +56,13 @@ var addDeployTargetConfigCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } - addDeployTargetConfig := &s.AddDeployTargetConfigInput{ - Project: uint(project.ID), + addDeployTargetConfig := &schema.AddDeployTargetConfigInput{ + Project: project.ID, Weight: weight, } if branches != "" { @@ -83,7 +75,7 @@ var addDeployTargetConfigCmd = &cobra.Command{ addDeployTargetConfig.DeployTarget = deploytarget } if yesNo(fmt.Sprintf("You are attempting to add a deploytarget configuration to project '%s', are you sure?", cmdProjectName)) { - deployTargetConfig, err := l.AddDeployTargetConfiguration(context.TODO(), addDeployTargetConfig, lc) + deployTargetConfig, err := lagoon.AddDeployTargetConfiguration(context.TODO(), addDeployTargetConfig, lc) if err != nil { return err } @@ -149,15 +141,17 @@ var updateDeployTargetConfigCmd = &cobra.Command{ if err != nil { return err } - if id == 0 { - return fmt.Errorf("missing arguments: deploytarget config id is not defined") + if err := requiredInputCheck("Deploytarget config id", strconv.Itoa(int(id))); err != nil { + return err } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) updateDeployTargetConfig := &schema.UpdateDeployTargetConfigInput{ @@ -225,20 +219,28 @@ var deleteDeployTargetConfigCmd = &cobra.Command{ if err != nil { return err } - if id == 0 { - return fmt.Errorf("missing arguments: deploytarget config id is not defined") + if err := requiredInputCheck("Deploytarget config id", strconv.Itoa(int(id)), "Project name", cmdProjectName); err != nil { + return err } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } + if project.Name == "" { + outputOptions.Error = fmt.Sprintf("No details for project '%s'", cmdProjectName) + output.RenderError(outputOptions.Error, outputOptions) + return nil + } if yesNo(fmt.Sprintf("You are attempting to delete deploytarget configuration with id '%d' from project '%s', are you sure?", id, cmdProjectName)) { result, err := lagoon.DeleteDeployTargetConfiguration(context.TODO(), int(id), int(project.ID), lc) @@ -264,17 +266,29 @@ var listDeployTargetConfigsCmd = &cobra.Command{ if err != nil { return err } + + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } + if project.Name == "" { + outputOptions.Error = fmt.Sprintf("No details for project '%s'", cmdProjectName) + output.RenderError(outputOptions.Error, outputOptions) + return nil + } deployTargetConfigs, err := lagoon.GetDeployTargetConfigs(context.TODO(), int(project.ID), lc) if err != nil { return err diff --git a/cmd/environment.go b/cmd/environment.go index 3d1aab96..7875b94f 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -3,17 +3,14 @@ package cmd import ( "context" "fmt" - "os" "strings" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" "github.com/uselagoon/lagoon-cli/pkg/output" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" ) @@ -25,21 +22,37 @@ var deleteEnvCmd = &cobra.Command{ Use: "environment", Aliases: []string{"e"}, Short: "Delete an environment", - Run: func(cmd *cobra.Command, args []string) { + 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 + } // environmentFlags := parseEnvironmentFlags(*cmd.Flags()) //@TODO re-enable this at some point if more environment based commands are made available - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) if yesNo(fmt.Sprintf("You are attempting to delete environment '%s' from project '%s', are you sure?", cmdProjectEnvironment, cmdProjectName)) { - projectByName, err := eClient.DeleteEnvironment(cmdProjectName, cmdProjectEnvironment) - handleError(err) + environment, err := lagoon.DeleteEnvironment(context.TODO(), cmdProjectEnvironment, cmdProjectName, true, lc) + if err != nil { + return err + } resultData := output.Result{ - Result: string(projectByName), + Result: environment.DeleteEnvironment, } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -94,10 +107,8 @@ var updateEnvironmentCmd = &cobra.Command{ cmd.Flags().Visit(checkFlags) - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } current := lagoonCLIConfig.Current @@ -108,18 +119,22 @@ var updateEnvironmentCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if project.Name == "" { err = fmt.Errorf("project not found") } - handleError(err) - environment, err := l.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) if environment.Name == "" { err = fmt.Errorf("environment not found") } - handleError(err) + if err != nil { + return err + } - environmentFlags := s.UpdateEnvironmentPatchInput{ + environmentFlags := schema.UpdateEnvironmentPatchInput{ DeployBaseRef: nullStrCheck(deployBaseRef), DeployHeadRef: nullStrCheck(deployHeadRef), OpenshiftProjectName: nullStrCheck(namespace), @@ -132,22 +147,24 @@ var updateEnvironmentCmd = &cobra.Command{ environmentFlags.AutoIdle = &environmentAutoIdle } if environmentType != "" { - envType := s.EnvType(strings.ToUpper(environmentType)) - if validationErr := s.ValidateType(envType); validationErr != nil { + envType := schema.EnvType(strings.ToUpper(environmentType)) + if validationErr := schema.ValidateType(envType); validationErr != nil { handleError(validationErr) } environmentFlags.EnvironmentType = &envType } if deployT != "" { - deployType := s.DeployType(strings.ToUpper(deployT)) - if validationErr := s.ValidateType(deployType); validationErr != nil { + deployType := schema.DeployType(strings.ToUpper(deployT)) + if validationErr := schema.ValidateType(deployType); validationErr != nil { handleError(validationErr) } environmentFlags.DeployType = &deployType } - result, err := l.UpdateEnvironment(context.TODO(), environment.ID, environmentFlags, lc) - handleError(err) + result, err := lagoon.UpdateEnvironment(context.TODO(), environment.ID, environmentFlags, lc) + if err != nil { + return err + } resultData := output.Result{ Result: "success", @@ -178,16 +195,19 @@ var listBackupsCmd = &cobra.Command{ if err != nil { return err } - if cmdProjectEnvironment == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: Project name or environment name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err @@ -245,16 +265,19 @@ This returns a direct URL to the backup, this is a signed download link with a l if err != nil { return err } - if cmdProjectEnvironment == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: Project name or environment name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } + current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err diff --git a/cmd/get.go b/cmd/get.go index daaab7bf..bcccbe8c 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -2,16 +2,14 @@ package cmd import ( "context" - "encoding/json" "fmt" - "os" "strconv" + "strings" "github.com/spf13/cobra" - "github.com/spf13/pflag" "github.com/uselagoon/lagoon-cli/pkg/output" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" ) @@ -22,19 +20,6 @@ type GetFlags struct { RemoteID string `json:"remoteid,omitempty"` } -func parseGetFlags(flags pflag.FlagSet) GetFlags { - configMap := make(map[string]interface{}) - flags.VisitAll(func(f *pflag.Flag) { - if flags.Changed(f.Name) { - configMap[f.Name] = f.Value - } - }) - jsonStr, _ := json.Marshal(configMap) - parsedFlags := GetFlags{} - json.Unmarshal(jsonStr, &parsedFlags) - return parsedFlags -} - var getCmd = &cobra.Command{ Use: "get", Aliases: []string{"g"}, @@ -56,9 +41,8 @@ var getProjectCmd = &cobra.Command{ if err != nil { return err } - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - return nil + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token @@ -69,26 +53,35 @@ var getProjectCmd = &cobra.Command{ &token, debug) - project, err := l.GetProjectByName(context.TODO(), cmdProjectName, lc) + project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } - if project == nil { - output.RenderInfo(fmt.Sprintf("No details for project '%s'", cmdProjectName), outputOptions) + if project.Name == "" { + outputOptions.Error = fmt.Sprintf("No details for project '%s'\n", cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) return nil } DevEnvironments := 0 productionRoute := "none" deploymentsDisabled, err := strconv.ParseBool(strconv.Itoa(int(project.DeploymentsDisabled))) - handleError(err) + if err != nil { + return err + } autoIdle, err := strconv.ParseBool(strconv.Itoa(int(project.AutoIdle))) - handleError(err) + if err != nil { + return err + } factsUI, err := strconv.ParseBool(strconv.Itoa(int(project.FactsUI))) - handleError(err) + if err != nil { + return err + } problemsUI, err := strconv.ParseBool(strconv.Itoa(int(project.ProblemsUI))) - handleError(err) + if err != nil { + return err + } for _, environment := range project.Environments { if environment.EnvironmentType == "development" { DevEnvironments++ @@ -135,7 +128,6 @@ This returns information about a deployment, the logs of this build can also be if err != nil { return err } - buildName, err := cmd.Flags().GetString("name") if err != nil { return err @@ -144,6 +136,10 @@ This returns information about a deployment, the logs of this build can also be if err != nil { return err } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment, "Build name", buildName); err != nil { + return err + } + current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token lc := lclient.New( @@ -152,7 +148,7 @@ This returns information about a deployment, the logs of this build can also be lagoonCLIConfig.Lagoons[current].Version, &token, debug) - deployment, err := l.GetDeploymentByName(context.TODO(), cmdProjectName, cmdProjectEnvironment, buildName, showLogs, lc) + deployment, err := lagoon.GetDeploymentByName(context.TODO(), cmdProjectName, cmdProjectEnvironment, buildName, showLogs, lc) if err != nil { return err } @@ -200,23 +196,56 @@ var getEnvironmentCmd = &cobra.Command{ Use: "environment", Aliases: []string{"e"}, Short: "Get details about an environment", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name is not defined") - cmd.Help() - os.Exit(1) - } - returnedJSON, err := eClient.GetEnvironmentInfo(cmdProjectName, cmdProjectEnvironment) - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("No environment '%s' for project '%s'", cmdProjectEnvironment, cmdProjectName), outputOptions) - os.Exit(0) + 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 } - output.RenderOutput(dataMain, outputOptions) + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + + data := []output.Data{} + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", environment.ID)), + returnNonEmptyString(fmt.Sprintf("%v", environment.Name)), + returnNonEmptyString(fmt.Sprintf("%v", environment.EnvironmentType)), + returnNonEmptyString(fmt.Sprintf("%v", environment.DeployType)), + returnNonEmptyString(fmt.Sprintf("%v", environment.Created)), + returnNonEmptyString(fmt.Sprintf("%v", environment.OpenshiftProjectName)), + returnNonEmptyString(fmt.Sprintf("%v", environment.Route)), + returnNonEmptyString(fmt.Sprintf("%v", environment.Routes)), + returnNonEmptyString(fmt.Sprintf("%d", environment.AutoIdle)), + returnNonEmptyString(fmt.Sprintf("%v", environment.DeployTitle)), + returnNonEmptyString(fmt.Sprintf("%v", environment.DeployBaseRef)), + returnNonEmptyString(fmt.Sprintf("%v", environment.DeployHeadRef)), + }) + dataMain := output.Table{ + Header: []string{"ID", "EnvironmentName", "EnvironmentType", "DeployType", "Created", "OpenshiftProjectName", "Route", "Routes", "AutoIdle", "DeployTitle", "DeployBaseRef", "DeployHeadRef"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -224,24 +253,56 @@ var getProjectKeyCmd = &cobra.Command{ Use: "project-key", Aliases: []string{"pk"}, Short: "Get a projects public key", - Run: func(cmd *cobra.Command, args []string) { - getProjectFlags := parseGetFlags(*cmd.Flags()) - if getProjectFlags.Project == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) - } - returnedJSON, err := pClient.GetProjectKey(getProjectFlags.Project, revealValue) - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) + 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 err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + projectKey, err := lagoon.GetProjectKeyByName(context.TODO(), cmdProjectName, revealValue, lc) + if err != nil { + return err + } + projectKeys := []string{projectKey.PublicKey} + if projectKey.PrivateKey != "" { + projectKeys = append(projectKeys, strings.TrimSuffix(projectKey.PrivateKey, "\n")) + outputOptions.MultiLine = true + } + + var data []output.Data + data = append(data, projectKeys) + + dataMain := output.Table{ + Header: []string{"PublicKey"}, + Data: data, + } + if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("No project-key for project '%s'", getProjectFlags.Project), outputOptions) - os.Exit(0) + outputOptions.Error = fmt.Sprintf("No project-key for project '%s'", cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } - output.RenderOutput(dataMain, outputOptions) + if projectKey.PrivateKey != "" { + dataMain.Header = append(dataMain.Header, "PrivateKey") + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -249,10 +310,13 @@ var getToken = &cobra.Command{ Use: "token", Aliases: []string{"tk"}, Short: "Generates a Lagoon auth token (for use in, for example, graphQL queries)", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { token, err := retrieveTokenViaSsh() - handleError(err) + if err != nil { + return err + } fmt.Println(token) + return nil }, } @@ -284,7 +348,7 @@ var getOrganizationCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } diff --git a/cmd/groups.go b/cmd/groups.go index a5150917..b1ac7c39 100644 --- a/cmd/groups.go +++ b/cmd/groups.go @@ -2,34 +2,19 @@ package cmd import ( "context" - "encoding/json" "fmt" - "os" + "slices" "strings" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) -func parseGroup(flags pflag.FlagSet) api.Group { - configMap := make(map[string]interface{}) - flags.VisitAll(func(f *pflag.Flag) { - if flags.Changed(f.Name) { - configMap[f.Name] = f.Value - } - }) - jsonStr, _ := json.Marshal(configMap) - parsedFlags := api.Group{} - json.Unmarshal(jsonStr, &parsedFlags) - return parsedFlags -} - var addGroupCmd = &cobra.Command{ Use: "group", Aliases: []string{"g"}, @@ -69,27 +54,27 @@ var addGroupCmd = &cobra.Command{ debug) if organizationName != "" { - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } if organization.Name == "" { return fmt.Errorf("error querying organization by name") } - groupInput := s.AddGroupToOrganizationInput{ + groupInput := schema.AddGroupToOrganizationInput{ Name: groupName, Organization: organization.ID, AddOrgOwner: orgOwner, } - _, err = l.AddGroupToOrganization(context.TODO(), &groupInput, lc) + _, err = lagoon.AddGroupToOrganization(context.TODO(), &groupInput, lc) if err != nil { return err } } else { - groupInput := s.AddGroupInput{ + groupInput := schema.AddGroupInput{ Name: groupName, } - _, err = l.AddGroup(context.TODO(), &groupInput, lc) + _, err = lagoon.AddGroup(context.TODO(), &groupInput, lc) if err != nil { return err } @@ -113,46 +98,69 @@ var addUserToGroupCmd = &cobra.Command{ Use: "user-group", Aliases: []string{"ug"}, Short: "Add a user to a group in lagoon", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, RunE: func(cmd *cobra.Command, args []string) error { - gRole, err := cmd.Flags().GetString("role") + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + groupRole, err := cmd.Flags().GetString("role") + if err != nil { + return err + } + userEmail, err := cmd.Flags().GetString("email") if err != nil { return err } + cmd.Flags().Visit( func(f *pflag.Flag) { if f.Name == "role" { - gRole = strings.ToUpper(f.Value.String()) + groupRole = strings.ToUpper(f.Value.String()) } }, ) - if gRole == "" { + + if groupRole == "" { // if no role flag is provided, fallback to guest (previous behavior, could be removed though) - gRole = "GUEST" - } - userGroupRole := api.UserGroupRole{ - User: api.User{ - Email: strings.ToLower(userEmail), - }, - Group: api.Group{ - Name: groupName, - }, - Role: api.GroupRole(gRole), + groupRole = "GUEST" } - if userGroupRole.User.Email == "" || userGroupRole.Group.Name == "" || userGroupRole.Role == "" { - return fmt.Errorf("missing arguments: Email address, group name, or role is not defined") + + if groupRole != "" && !slices.Contains(groupRoles, strings.ToLower(groupRole)) { + return fmt.Errorf("role '%s' is not valid - valid roles include \"guest\", \"reporter\", \"developer\", \"maintainer\", \"owner\"", groupRole) } - var customReqResult []byte - customReqResult, err = uClient.AddUserToGroup(userGroupRole) - if err != nil { + + if err := requiredInputCheck("Group name", groupName, "Email address", userEmail); err != nil { return err } - returnResultData := map[string]interface{}{} - if err = json.Unmarshal([]byte(customReqResult), &returnResultData); err != nil { + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + userGroupRole := &schema.UserGroupRoleInput{ + UserEmail: userEmail, + GroupName: groupName, + GroupRole: schema.GroupRole(groupRole), + } + _, err = lagoon.AddUserToGroup(context.TODO(), userGroupRole, lc) + if err != nil { return err } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", } output.RenderResult(resultData, outputOptions) return nil @@ -163,34 +171,61 @@ var addProjectToGroupCmd = &cobra.Command{ Use: "project-group", Aliases: []string{"pg"}, Short: "Add a project to a group in lagoon", - Run: func(cmd *cobra.Command, args []string) { - projectGroup := api.ProjectGroups{ - Project: api.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 + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Group name", groupName, "Project name", cmdProjectName); err != nil { + return err + } + + projectGroup := &schema.ProjectGroupsInput{ + Project: schema.ProjectInput{ Name: cmdProjectName, }, - Groups: []api.Group{ + Groups: []schema.GroupInput{ { Name: groupName, }, }, } - if projectGroup.Project.Name == "" || len(projectGroup.Groups) == 0 { - output.RenderError("Missing arguments: Project name or group name is not defined", outputOptions) - cmd.Help() - os.Exit(1) - } - var customReqResult []byte - var err error - customReqResult, err = uClient.AddProjectToGroup(projectGroup) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + if len(project.Name) == 0 { + outputOptions.Error = fmt.Sprintf("Project '%s' not found", cmdProjectName) + output.RenderError(outputOptions.Error, outputOptions) + return nil + } + _, err = lagoon.AddProjectToGroup(context.TODO(), projectGroup, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -198,34 +233,56 @@ var deleteUserFromGroupCmd = &cobra.Command{ Use: "user-group", Aliases: []string{"ug"}, Short: "Delete a user from a group in lagoon", - Run: func(cmd *cobra.Command, args []string) { - userGroupRole := api.UserGroup{ - User: api.User{ - Email: strings.ToLower(userEmail), - }, - Group: api.Group{ - Name: groupName, - }, + 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 + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + userEmail, err := cmd.Flags().GetString("email") + if err != nil { + return err } - if userGroupRole.User.Email == "" || userGroupRole.Group.Name == "" { - output.RenderError("Missing arguments: Email address or group name is not defined", outputOptions) - cmd.Help() - os.Exit(1) - } - var customReqResult []byte - var err error - if yesNo(fmt.Sprintf("You are attempting to delete user '%s' from group '%s', are you sure?", userGroupRole.User.Email, userGroupRole.Group.Name)) { - customReqResult, err = uClient.RemoveUserFromGroup(userGroupRole) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + + if err := requiredInputCheck("Group name", groupName, "Email address", userEmail); err != nil { + return err + } + + user := &schema.UserGroupInput{ + UserEmail: userEmail, + GroupName: groupName, + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + if yesNo(fmt.Sprintf("You are attempting to delete user '%s' from group '%s', are you sure?", userEmail, groupName)) { + result, err := lagoon.RemoveUserFromGroup(context.TODO(), user, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", + ResultData: map[string]interface{}{ + "id": result.ID, + }, } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -233,59 +290,103 @@ var deleteProjectFromGroupCmd = &cobra.Command{ Use: "project-group", Aliases: []string{"pg"}, Short: "Delete a project from a group in lagoon", - Run: func(cmd *cobra.Command, args []string) { - projectGroup := api.ProjectGroups{ - Project: api.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 + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Group name", groupName, "Project name", cmdProjectName); err != nil { + return err + } + + projectGroup := &schema.ProjectGroupsInput{ + Project: schema.ProjectInput{ Name: cmdProjectName, }, - Groups: []api.Group{ + Groups: []schema.GroupInput{ { Name: groupName, }, }, } - if projectGroup.Project.Name == "" || len(projectGroup.Groups) == 0 { - output.RenderError("Missing arguments: Project name or group name is not defined", outputOptions) - cmd.Help() - os.Exit(1) + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + if len(project.Name) == 0 { + outputOptions.Error = fmt.Sprintf("Project '%s' not found", cmdProjectName) + output.RenderError(outputOptions.Error, outputOptions) + return nil } - var customReqResult []byte - var err error + if yesNo(fmt.Sprintf("You are attempting to delete project '%s' from group '%s', are you sure?", projectGroup.Project.Name, projectGroup.Groups[0].Name)) { - customReqResult, err = uClient.RemoveGroupsFromProject(projectGroup) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + _, err = lagoon.RemoveGroupsFromProject(context.TODO(), projectGroup, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", } output.RenderResult(resultData, outputOptions) } + return nil }, } var deleteGroupCmd = &cobra.Command{ Use: "group", Aliases: []string{"g"}, Short: "Delete a group from lagoon", - Run: func(cmd *cobra.Command, args []string) { - groupFlags := parseGroup(*cmd.Flags()) - if groupFlags.Name == "" { - fmt.Println("Missing arguments: Group name is not defined") - cmd.Help() - os.Exit(1) - } - var customReqResult []byte - var err error - if yesNo(fmt.Sprintf("You are attempting to delete group '%s', are you sure?", groupFlags.Name)) { - customReqResult, err = uClient.DeleteGroup(groupFlags) - handleError(err) + 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 + } + 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, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + if yesNo(fmt.Sprintf("You are attempting to delete group '%s', are you sure?", groupName)) { + _, err := lagoon.DeleteGroup(context.TODO(), groupName, lc) + if err != nil { + return err + } resultData := output.Result{ - Result: string(customReqResult), + Result: "success", } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -295,10 +396,10 @@ func init() { addGroupCmd.Flags().Bool("owner", false, "Organization owner only: Flag to grant yourself ownership of this group") addUserToGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") addUserToGroupCmd.Flags().StringP("role", "R", "", "Role in the group [owner, maintainer, developer, reporter, guest]") - addUserToGroupCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") - addProjectToGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") - deleteUserFromGroupCmd.Flags().StringVarP(&groupName, "name", "N", "", "Name of the group") - deleteUserFromGroupCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") + addUserToGroupCmd.Flags().StringP("email", "E", "", "Email address of the user") + addProjectToGroupCmd.Flags().StringP("name", "N", "", "Name of the group") + deleteUserFromGroupCmd.Flags().StringP("name", "N", "", "Name of the group") + deleteUserFromGroupCmd.Flags().StringP("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") diff --git a/cmd/helpers.go b/cmd/helpers.go index e2cd5b9c..8eb9433a 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -7,10 +7,10 @@ import ( "regexp" "strings" + "github.com/uselagoon/machinery/api/schema" + "github.com/guregu/null" "github.com/spf13/pflag" - - "github.com/uselagoon/lagoon-cli/internal/schema" ) // makeSafe ensures that any string is dns safe diff --git a/cmd/helpers_test.go b/cmd/helpers_test.go index b54b3abd..df1ffda6 100644 --- a/cmd/helpers_test.go +++ b/cmd/helpers_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/uselagoon/lagoon-cli/internal/schema" + "github.com/uselagoon/machinery/api/schema" "github.com/guregu/null" "github.com/spf13/pflag" diff --git a/cmd/list.go b/cmd/list.go index 1e36e5ef..ee8f126a 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -2,20 +2,14 @@ package cmd import ( "context" - "encoding/json" "fmt" - "os" "strconv" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - ls "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" ) // ListFlags . @@ -37,18 +31,55 @@ var listProjectsCmd = &cobra.Command{ Use: "projects", Aliases: []string{"p"}, Short: "List all projects you have access to (alias: p)", - Run: func(cmd *cobra.Command, args []string) { - returnedJSON, err := pClient.ListAllProjects() - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo("No access to any projects in Lagoon", outputOptions) - os.Exit(0) + 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 } - output.RenderOutput(dataMain, outputOptions) + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + projects, err := lagoon.ListAllProjects(context.TODO(), lc) + if err != nil { + return err + } + + data := []output.Data{} + for _, project := range *projects { + var devEnvironments = 0 + for _, environment := range project.Environments { + if environment.EnvironmentType == "development" { + devEnvironments++ + } + } + + 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.ProductionEnvironment)), + returnNonEmptyString(fmt.Sprintf("%v/%v", devEnvironments, project.DevelopmentEnvironmentsLimit)), + }) + } + if len(data) == 0 { + outputOptions.Error = "No access to any projects in Lagoon\n" + } + dataMain := output.Table{ + Header: []string{"ID", "ProjectName", "GitUrl", "ProductionEnvironment", "DevEnvironments"}, + Data: data, + } + + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -66,11 +97,12 @@ var listDeployTargetsCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) deploytargets, err := lagoon.ListDeployTargets(context.TODO(), lc) if err != nil { @@ -120,18 +152,44 @@ var listGroupsCmd = &cobra.Command{ Use: "groups", Aliases: []string{"g"}, Short: "List groups you have access to (alias: g)", - Run: func(cmd *cobra.Command, args []string) { - returnedJSON, err := uClient.ListGroups("") - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo("This account is not in any groups", outputOptions) - os.Exit(0) + 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, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + groups, err := lagoon.ListAllGroups(context.TODO(), lc) + if err != nil { + return err } - output.RenderOutput(dataMain, outputOptions) + data := []output.Data{} + for _, group := range *groups { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", group.ID)), + returnNonEmptyString(fmt.Sprintf("%v", group.Name)), + }) + } + if len(data) == 0 { + outputOptions.Error = "This account is not in any groups\n" + } + dataMain := output.Table{ + Header: []string{"ID", "Name"}, + Data: data, + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -139,35 +197,84 @@ var listGroupProjectsCmd = &cobra.Command{ Use: "group-projects", Aliases: []string{"gp"}, Short: "List projects in a group (alias: gp)", - 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 + } + groupName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + listAllProjects, err := cmd.Flags().GetBool("all-projects") + if err != nil { + return err + } + if !listAllProjects { - if groupName == "" { - fmt.Println("Missing arguments: Group name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Group name", groupName); err != nil { + return err } } - var returnedJSON []byte - var err error + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + var groupProjects *[]schema.Group + if listAllProjects { - returnedJSON, err = uClient.ListGroupProjects("", listAllProjects) + groupProjects, err = lagoon.GetGroupProjects(context.TODO(), "", lc) + if err != nil { + return err + } } else { - returnedJSON, err = uClient.ListGroupProjects(groupName, listAllProjects) + groupProjects, err = lagoon.GetGroupProjects(context.TODO(), groupName, lc) + if err != nil { + return err + } + } + var data []output.Data + idx := 0 + for _, group := range *groupProjects { + for _, project := range group.Projects { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", project.ID)), + returnNonEmptyString(project.Name), + }) + if listAllProjects { + data[idx] = append(data[idx], returnNonEmptyString(group.Name)) + } + idx++ + } } - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { + if len(data) == 0 { if !listAllProjects { - output.RenderInfo(fmt.Sprintf("There are no projects in group '%s'", groupName), outputOptions) + outputOptions.Error = fmt.Sprintf("There are no projects in group '%s'\n", groupName) } else { - output.RenderInfo("There are no projects in any groups", outputOptions) + outputOptions.Error = "There are no projects in any groups\n" } - os.Exit(0) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } - output.RenderOutput(dataMain, outputOptions) + dataMain := output.Table{ + Header: []string{"ID", "ProjectName"}, + Data: data, + } + if listAllProjects { + dataMain.Header = append(dataMain.Header, "GroupName") + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -183,10 +290,8 @@ var listEnvironmentsCmd = &cobra.Command{ if err != nil { return err } - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } current := lagoonCLIConfig.Current @@ -197,13 +302,15 @@ var listEnvironmentsCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - environments, err := l.GetEnvironmentsByProjectName(context.TODO(), cmdProjectName, lc) + environments, err := lagoon.GetEnvironmentsByProjectName(context.TODO(), cmdProjectName, lc) if err != nil { return err } if len(*environments) == 0 { outputOptions.Error = fmt.Sprintf("No environments found for project '%s'\n", cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } data := []output.Data{} @@ -239,10 +346,8 @@ var listVariablesCmd = &cobra.Command{ return validateTokenE(cmdLagoon) }, RunE: func(cmd *cobra.Command, args []string) error { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } reveal, err := cmd.Flags().GetBool("reveal") if err != nil { @@ -253,11 +358,12 @@ var listVariablesCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) in := &schema.EnvVariableByProjectEnvironmentNameInput{ Project: cmdProjectName, @@ -297,10 +403,12 @@ var listVariablesCmd = &cobra.Command{ } if len(data) == 0 { if cmdProjectEnvironment != "" { - outputOptions.Error = fmt.Sprintf("There are no variables for environment '%s' in project '%s'", cmdProjectEnvironment, cmdProjectName) + outputOptions.Error = fmt.Sprintf("There are no variables for environment '%s' in project '%s'\n", cmdProjectEnvironment, cmdProjectName) } else { outputOptions.Error = fmt.Sprintf("There are no variables for project '%s'\n", cmdProjectName) } + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } output.RenderOutput(output.Table{ Header: header, @@ -314,23 +422,61 @@ var listDeploymentsCmd = &cobra.Command{ Use: "deployments", Aliases: []string{"d"}, Short: "List deployments for an environment (alias: d)", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name is not defined") - cmd.Help() - os.Exit(1) - } - returnedJSON, err := eClient.GetEnvironmentDeployments(cmdProjectName, cmdProjectEnvironment) - handleError(err) - - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("There are no deployments for environment '%s' in project '%s'", cmdProjectEnvironment, cmdProjectName), outputOptions) - os.Exit(0) + 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 + } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + + deployments, err := lagoon.GetDeploymentsByEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) + if err != nil { + return err + } + + data := []output.Data{} + for _, deployment := range deployments.Deployments { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", 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)), + }) + } + + if len(data) == 0 { + outputOptions.Error = fmt.Sprintf("There are no deployments for environment '%s' in project '%s'\n", cmdProjectEnvironment, cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil + } + dataMain := output.Table{ + Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed"}, + Data: data, } output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -338,23 +484,62 @@ var listTasksCmd = &cobra.Command{ Use: "tasks", Aliases: []string{"t"}, Short: "List tasks for an environment (alias: t)", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name is not defined") - cmd.Help() - os.Exit(1) - } - returnedJSON, err := eClient.GetEnvironmentTasks(cmdProjectName, cmdProjectEnvironment) - handleError(err) - - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) - if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("There are no tasks for environment '%s' in project '%s'", cmdProjectEnvironment, cmdProjectName), outputOptions) - os.Exit(0) + 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 + } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + + tasks, err := lagoon.GetTasksByEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) + if err != nil { + return err + } + + data := []output.Data{} + for _, task := range tasks.Tasks { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%d", task.ID)), + returnNonEmptyString(fmt.Sprintf("%v", task.RemoteID)), + returnNonEmptyString(fmt.Sprintf("%v", task.Name)), + returnNonEmptyString(fmt.Sprintf("%v", task.Status)), + returnNonEmptyString(fmt.Sprintf("%v", task.Created)), + returnNonEmptyString(fmt.Sprintf("%v", task.Started)), + returnNonEmptyString(fmt.Sprintf("%v", task.Completed)), + returnNonEmptyString(fmt.Sprintf("%v", task.Service)), + }) + } + + if len(data) == 0 { + outputOptions.Error = fmt.Sprintf("There are no tasks for environment '%s' in project '%s'\n", cmdProjectEnvironment, cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil + } + dataMain := output.Table{ + Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed", "Service"}, + Data: data, } output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -364,7 +549,7 @@ var listUsersCmd = &cobra.Command{ Short: "List all users in groups", Long: `List all users in groups in lagoon, this only shows users that are in groups. If no group name is provided, all groups are queried. -Without a group name, this query may time out in large Lagoon installs.`, +Without a group name, this query may time out in large Lagoon instalschema.`, PreRunE: func(_ *cobra.Command, _ []string) error { return validateTokenE(cmdLagoon) }, @@ -388,7 +573,7 @@ Without a group name, this query may time out in large Lagoon installs.`, data := []output.Data{} if groupName != "" { // if a groupName is provided, use the groupbyname resolver - groupMembers, err := l.ListGroupMembers(context.TODO(), groupName, lc) + groupMembers, err := lagoon.ListGroupMembers(context.TODO(), groupName, lc) if err != nil { return err } @@ -402,7 +587,7 @@ Without a group name, this query may time out in large Lagoon installs.`, } } else { // otherwise allgroups query - groupMembers, err := l.ListAllGroupMembers(context.TODO(), groupName, lc) + groupMembers, err := lagoon.ListAllGroupMembers(context.TODO(), groupName, lc) if err != nil { return err } @@ -452,7 +637,7 @@ This query can take a long time to run if there are a lot of users.`, lagoonCLIConfig.Lagoons[current].Version, &token, debug) - allUsers, err := l.AllUsers(context.TODO(), ls.AllUsersFilter{ + allUsers, err := lagoon.AllUsers(context.TODO(), schema.AllUsersFilter{ Email: emailAddress, }, lc) if err != nil { @@ -494,8 +679,8 @@ var listUsersGroupsCmd = &cobra.Command{ if err != nil { return err } - if emailAddress == "" { - return fmt.Errorf("missing arguments: email address is not defined") + if err := requiredInputCheck("Email Address", emailAddress); err != nil { + return err } current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token @@ -505,7 +690,7 @@ var listUsersGroupsCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - allUsers, err := l.GetUserByEmail(context.TODO(), emailAddress, lc) + allUsers, err := lagoon.GetUserByEmail(context.TODO(), emailAddress, lc) if err != nil { return err } @@ -532,38 +717,55 @@ var listInvokableTasks = &cobra.Command{ Aliases: []string{"dcc"}, Short: "Print a list of invokable tasks", Long: "Print a list of invokable user defined tasks registered against an environment", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name are 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") + if err != nil { + return err + } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } - taskResult, err := eClient.ListInvokableAdvancedTaskDefinitions(cmdProjectName, cmdProjectEnvironment) - handleError(err) - var taskList []api.AdvancedTask - err = json.Unmarshal([]byte(taskResult), &taskList) + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { - fmt.Println(err) - os.Exit(1) + return err } - - var taskListData []output.Data - for _, task := range taskList { - taskListData = append(taskListData, []string{task.Name, task.Description}) + tasks, err := lagoon.GetInvokableAdvancedTaskDefinitionsByEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) + if err != nil { + return err } - var dataMain output.Table - dataMain.Header = []string{"Task Name", "Description"} - - dataMain.Data = taskListData + data := []output.Data{} + for _, task := range tasks.AdvancedTasks { + data = append(data, []string{ + returnNonEmptyString(task.Name), + returnNonEmptyString(task.Description), + }) + } - if len(dataMain.Data) == 0 { - output.RenderInfo("There are no user defined tasks for this environment", outputOptions) - os.Exit(0) + if len(data) == 0 { + outputOptions.Error = "There are no user defined tasks for this environment\n" + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil + } + dataMain := output.Table{ + Header: []string{"Task Name", "Description"}, + Data: data, } output.RenderOutput(dataMain, outputOptions) + return nil }, } @@ -600,11 +802,15 @@ var listProjectGroupsCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - projectGroups, err := l.GetProjectGroups(context.TODO(), cmdProjectName, lc) - handleError(err) + projectGroups, err := lagoon.GetProjectGroups(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } if len(projectGroups.Groups) == 0 { outputOptions.Error = fmt.Sprintf("There are no groups for project '%s'\n", cmdProjectName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } data := []output.Data{} @@ -657,20 +863,22 @@ var listOrganizationProjectsCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } if organization.Name == "" { return fmt.Errorf("error querying organization by name") } - orgProjects, err := l.ListProjectsByOrganizationID(context.TODO(), organization.ID, lc) + orgProjects, err := lagoon.ListProjectsByOrganizationID(context.TODO(), organization.ID, lc) if err != nil { return err } if len(*orgProjects) == 0 { outputOptions.Error = fmt.Sprintf("No associated projects found for organization '%s'\n", organizationName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } data := []output.Data{} @@ -719,19 +927,21 @@ var listOrganizationGroupsCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } if organization.Name == "" { return fmt.Errorf("error querying organization by name") } - orgGroups, err := l.ListGroupsByOrganizationID(context.TODO(), organization.ID, lc) + orgGroups, err := lagoon.ListGroupsByOrganizationID(context.TODO(), organization.ID, lc) if err != nil { return err } if len(*orgGroups) == 0 { outputOptions.Error = fmt.Sprintf("No associated groups found for organization '%s'\n", organizationName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } data := []output.Data{} @@ -784,12 +994,14 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - deployTargets, err := l.ListDeployTargetsByOrganizationNameOrID(context.TODO(), nullStrCheck(organizationName), nullUintCheck(organizationID), lc) + deployTargets, err := lagoon.ListDeployTargetsByOrganizationNameOrID(context.TODO(), nullStrCheck(organizationName), nullUintCheck(organizationID), lc) if err != nil { return err } if len(*deployTargets) == 0 { outputOptions.Error = fmt.Sprintf("No associated deploy targets found for organization '%s'\n", organizationName) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + return nil } data := []output.Data{} @@ -841,14 +1053,14 @@ var ListOrganizationUsersCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - organization, err := l.GetOrganizationByName(context.Background(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.Background(), organizationName, lc) if err != nil { return err } if organization.Name == "" { return fmt.Errorf("error querying organization by name") } - users, err := l.UsersByOrganization(context.TODO(), organization.ID, lc) + users, err := lagoon.UsersByOrganization(context.TODO(), organization.ID, lc) if err != nil { return err } @@ -895,7 +1107,7 @@ var listOrganizationsCmd = &cobra.Command{ &token, debug) - organizations, err := l.AllOrganizations(context.TODO(), lc) + organizations, err := lagoon.AllOrganizations(context.TODO(), lc) if err != nil { return err } @@ -948,7 +1160,8 @@ func init() { listUsersGroupsCmd.Flags().StringP("email-address", "E", "", "The email address of a user") 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") + listGroupProjectsCmd.Flags().StringP("name", "N", "", "Name of the group to list projects in") + listGroupProjectsCmd.Flags().BoolP("all-projects", "", false, "All projects") listVariablesCmd.Flags().BoolP("reveal", "", false, "Reveal the variable values") listOrganizationProjectsCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated projects for") ListOrganizationUsersCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated users for") diff --git a/cmd/notificationsemail.go b/cmd/notificationsemail.go index 6d9df29c..bdd62a1a 100644 --- a/cmd/notificationsemail.go +++ b/cmd/notificationsemail.go @@ -1,20 +1,15 @@ package cmd import ( - "bytes" "context" "encoding/json" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" ) var addNotificationEmailCmd = &cobra.Command{ @@ -44,8 +39,8 @@ It does not configure a project to send notifications to email though, you need if err != nil { return err } - if name == "" || email == "" { - return fmt.Errorf("missing arguments: name or email is not defined") + if err := requiredInputCheck("Name", name, "Email", email); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to create an email notification '%s' with email address '%s', are you sure?", name, email)) { current := lagoonCLIConfig.Current @@ -57,13 +52,13 @@ It does not configure a project to send notifications to email though, you need &token, debug) - notification := s.AddNotificationEmailInput{ + notification := schema.AddNotificationEmailInput{ Name: name, EmailAddress: email, Organization: &organizationID, } - result, err := l.AddNotificationEmail(context.TODO(), ¬ification, lc) + result, err := lagoon.AddNotificationEmail(context.TODO(), ¬ification, lc) if err != nil { return err } @@ -74,7 +69,7 @@ It does not configure a project to send notifications to email though, you need returnNonEmptyString(fmt.Sprintf("%v", result.EmailAddress)), } if result.Organization != nil { - organization, err := l.GetOrganizationByID(context.TODO(), organizationID, lc) + organization, err := lagoon.GetOrganizationByID(context.TODO(), organizationID, lc) if err != nil { return err } @@ -111,23 +106,25 @@ This command is used to add an existing email notification in Lagoon to a projec if err != nil { return err } + name, err := cmd.Flags().GetString("name") if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Notification name", name, "Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to add email notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.AddNotificationToProjectInput{ - NotificationType: api.EmailNotification, + NotificationType: schema.EmailNotification, NotificationName: name, Project: cmdProjectName, } @@ -169,7 +166,7 @@ var listProjectEmailsCmd = &cobra.Command{ &token, debug) - result, err := l.GetProjectNotificationEmail(context.TODO(), cmdProjectName, lc) + result, err := lagoon.GetProjectNotificationEmail(context.TODO(), cmdProjectName, lc) if err != nil { return err } @@ -212,11 +209,12 @@ var listAllEmailsCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.GetAllNotificationEmail(context.TODO(), lc) if err != nil { @@ -263,19 +261,20 @@ var deleteProjectEmailNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete email notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.RemoveNotificationFromProjectInput{ - NotificationType: api.EmailNotification, + NotificationType: schema.EmailNotification, NotificationName: name, Project: cmdProjectName, } @@ -308,16 +307,17 @@ var deleteEmailNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete email notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeleteNotificationEmail(context.TODO(), name, lc) if err != nil { @@ -356,25 +356,25 @@ var updateEmailNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } - patch := schema.AddNotificationEmailInput{ - Name: newname, - EmailAddress: email, + patch := schema.UpdateNotificationEmailPatchInput{ + Name: nullStrCheck(newname), + EmailAddress: nullStrCheck(email), } - b1, _ := json.Marshal(patch) - if bytes.Equal(b1, []byte("{}")) { + if patch == (schema.UpdateNotificationEmailPatchInput{}) { return fmt.Errorf("missing arguments: either email or newname must be defined") } if yesNo(fmt.Sprintf("You are attempting to update email notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.UpdateNotificationEmailInput{ diff --git a/cmd/notificationsrocketchat.go b/cmd/notificationsrocketchat.go index 9e212ef5..f1130028 100644 --- a/cmd/notificationsrocketchat.go +++ b/cmd/notificationsrocketchat.go @@ -1,20 +1,15 @@ package cmd import ( - "bytes" "context" "encoding/json" "fmt" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) @@ -49,8 +44,8 @@ It does not configure a project to send notifications to RocketChat though, you if err != nil { return err } - if name == "" || channel == "" || webhook == "" { - return fmt.Errorf("missing arguments: name, webhook, or email is not defined") + if err := requiredInputCheck("Notification name", name, "Channel", channel, "Webhook", webhook); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to create an RocketChat notification '%s' with webhook '%s' channel '%s', are you sure?", name, webhook, channel)) { current := lagoonCLIConfig.Current @@ -62,14 +57,14 @@ It does not configure a project to send notifications to RocketChat though, you &token, debug) - notification := s.AddNotificationRocketChatInput{ + notification := schema.AddNotificationRocketChatInput{ Name: name, Webhook: webhook, Channel: channel, Organization: &organizationID, } - result, err := l.AddNotificationRocketChat(context.TODO(), ¬ification, lc) + result, err := lagoon.AddNotificationRocketChat(context.TODO(), ¬ification, lc) if err != nil { return err } @@ -81,7 +76,7 @@ It does not configure a project to send notifications to RocketChat though, you returnNonEmptyString(fmt.Sprintf("%v", result.Channel)), } if result.Organization != nil { - organization, err := l.GetOrganizationByID(context.TODO(), organizationID, lc) + organization, err := lagoon.GetOrganizationByID(context.TODO(), organizationID, lc) if err != nil { return err } @@ -123,22 +118,25 @@ This command is used to add an existing RocketChat notification in Lagoon to a p if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Notification name", name, "Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to add RocketChat notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + notification := &schema.AddNotificationToProjectInput{ - NotificationType: api.RocketChatNotification, + NotificationType: schema.RocketChatNotification, NotificationName: name, Project: cmdProjectName, } + _, err := lagoon.AddNotificationToProject(context.TODO(), notification, lc) if err != nil { return err @@ -177,7 +175,7 @@ var listProjectRocketChatsCmd = &cobra.Command{ &token, debug) - result, err := l.GetProjectNotificationRocketChat(context.TODO(), cmdProjectName, lc) + result, err := lagoon.GetProjectNotificationRocketChat(context.TODO(), cmdProjectName, lc) if err != nil { return err } @@ -222,11 +220,12 @@ var listAllRocketChatsCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.GetAllNotificationRocketChat(context.TODO(), lc) if err != nil { @@ -275,19 +274,20 @@ var deleteProjectRocketChatNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete RocketChat notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.RemoveNotificationFromProjectInput{ - NotificationType: api.RocketChatNotification, + NotificationType: schema.RocketChatNotification, NotificationName: name, Project: cmdProjectName, } @@ -320,16 +320,17 @@ var deleteRocketChatNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete RocketChat notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeleteNotificationRocketChat(context.TODO(), name, lc) if err != nil { @@ -372,26 +373,26 @@ var updateRocketChatNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } - patch := schema.AddNotificationRocketChatInput{ - Name: newname, - Webhook: webhook, - Channel: channel, + patch := schema.UpdateNotificationRocketChatPatchInput{ + Name: nullStrCheck(newname), + Webhook: nullStrCheck(webhook), + Channel: nullStrCheck(channel), } - b1, _ := json.Marshal(patch) - if bytes.Equal(b1, []byte("{}")) { + if patch == (schema.UpdateNotificationRocketChatPatchInput{}) { return fmt.Errorf("missing arguments: either channel, webhook, or newname must be defined") } if yesNo(fmt.Sprintf("You are attempting to update RocketChat notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.UpdateNotificationRocketChatInput{ diff --git a/cmd/notificationsslack.go b/cmd/notificationsslack.go index 26c1c4f4..7032f3a2 100644 --- a/cmd/notificationsslack.go +++ b/cmd/notificationsslack.go @@ -1,20 +1,15 @@ package cmd import ( - "bytes" "context" "encoding/json" "fmt" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) @@ -49,8 +44,8 @@ It does not configure a project to send notifications to Slack though, you need if err != nil { return err } - if name == "" || channel == "" || webhook == "" { - return fmt.Errorf("missing arguments: name, webhook, or email is not defined") + if err := requiredInputCheck("Notification name", name, "Channel", channel, "Webhook", webhook); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to create an Slack notification '%s' with webhook '%s' channel '%s', are you sure?", name, webhook, channel)) { current := lagoonCLIConfig.Current @@ -62,14 +57,14 @@ It does not configure a project to send notifications to Slack though, you need &token, debug) - notification := s.AddNotificationSlackInput{ + notification := schema.AddNotificationSlackInput{ Name: name, Webhook: webhook, Channel: channel, Organization: &organizationID, } - result, err := l.AddNotificationSlack(context.TODO(), ¬ification, lc) + result, err := lagoon.AddNotificationSlack(context.TODO(), ¬ification, lc) if err != nil { return err } @@ -81,7 +76,7 @@ It does not configure a project to send notifications to Slack though, you need returnNonEmptyString(fmt.Sprintf("%v", result.Channel)), } if result.Organization != nil { - organization, err := l.GetOrganizationByID(context.TODO(), organizationID, lc) + organization, err := lagoon.GetOrganizationByID(context.TODO(), organizationID, lc) if err != nil { return err } @@ -123,19 +118,20 @@ This command is used to add an existing Slack notification in Lagoon to a projec if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Notification name", name, "Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to add Slack notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.AddNotificationToProjectInput{ - NotificationType: api.SlackNotification, + NotificationType: schema.SlackNotification, NotificationName: name, Project: cmdProjectName, } @@ -177,7 +173,7 @@ var listProjectSlacksCmd = &cobra.Command{ &token, debug) - result, err := l.GetProjectNotificationSlack(context.TODO(), cmdProjectName, lc) + result, err := lagoon.GetProjectNotificationSlack(context.TODO(), cmdProjectName, lc) if err != nil { return err } @@ -222,11 +218,12 @@ var listAllSlacksCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.GetAllNotificationSlack(context.TODO(), lc) if err != nil { @@ -275,19 +272,20 @@ var deleteProjectSlackNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete Slack notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.RemoveNotificationFromProjectInput{ - NotificationType: api.SlackNotification, + NotificationType: schema.SlackNotification, NotificationName: name, Project: cmdProjectName, } @@ -320,16 +318,17 @@ var deleteSlackNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete Slack notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeleteNotificationSlack(context.TODO(), name, lc) if err != nil { @@ -372,26 +371,26 @@ var updateSlackNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } - patch := schema.AddNotificationSlackInput{ - Name: newname, - Webhook: webhook, - Channel: channel, + patch := schema.UpdateNotificationSlackPatchInput{ + Name: nullStrCheck(newname), + Webhook: nullStrCheck(webhook), + Channel: nullStrCheck(channel), } - b1, _ := json.Marshal(patch) - if bytes.Equal(b1, []byte("{}")) { + if patch == (schema.UpdateNotificationSlackPatchInput{}) { return fmt.Errorf("missing arguments: either channel, webhook, or newname must be defined") } if yesNo(fmt.Sprintf("You are attempting to update Slack notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.UpdateNotificationSlackInput{ diff --git a/cmd/notificationsteams.go b/cmd/notificationsteams.go index bb8c0631..d267fb66 100644 --- a/cmd/notificationsteams.go +++ b/cmd/notificationsteams.go @@ -1,20 +1,15 @@ package cmd import ( - "bytes" "context" "encoding/json" "fmt" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) @@ -45,8 +40,8 @@ It does not configure a project to send notifications to Microsoft Teams though, if err != nil { return err } - if name == "" || webhook == "" { - return fmt.Errorf("missing arguments: name or webhook is not defined") + if err := requiredInputCheck("Notification name", name, "Webhook", webhook); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to create a Microsoft Teams notification '%s' with webhook url '%s', are you sure?", name, webhook)) { current := lagoonCLIConfig.Current @@ -58,13 +53,13 @@ It does not configure a project to send notifications to Microsoft Teams though, &token, debug) - notification := s.AddNotificationMicrosoftTeamsInput{ + notification := schema.AddNotificationMicrosoftTeamsInput{ Name: name, Webhook: webhook, Organization: &organizationID, } - result, err := l.AddNotificationMicrosoftTeams(context.TODO(), ¬ification, lc) + result, err := lagoon.AddNotificationMicrosoftTeams(context.TODO(), ¬ification, lc) if err != nil { return err } @@ -75,7 +70,7 @@ It does not configure a project to send notifications to Microsoft Teams though, returnNonEmptyString(fmt.Sprintf("%v", result.Webhook)), } if result.Organization != nil { - organization, err := l.GetOrganizationByID(context.TODO(), organizationID, lc) + organization, err := lagoon.GetOrganizationByID(context.TODO(), organizationID, lc) if err != nil { return err } @@ -116,19 +111,20 @@ This command is used to add an existing Microsoft Teams notification in Lagoon t if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Notification name", name, "Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to add Microsoft Teams notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.AddNotificationToProjectInput{ - NotificationType: api.MicrosoftTeamsNotification, + NotificationType: schema.MicrosoftTeamsNotification, NotificationName: name, Project: cmdProjectName, } @@ -170,7 +166,7 @@ var listProjectMicrosoftTeamsCmd = &cobra.Command{ &token, debug) - result, err := l.GetProjectNotificationMicrosoftTeams(context.TODO(), cmdProjectName, lc) + result, err := lagoon.GetProjectNotificationMicrosoftTeams(context.TODO(), cmdProjectName, lc) if err != nil { return err } @@ -213,11 +209,12 @@ var listAllMicrosoftTeamsCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.GetAllNotificationMicrosoftTeams(context.TODO(), lc) if err != nil { @@ -264,19 +261,20 @@ var deleteProjectMicrosoftTeamsNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete Microsoft Teams notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.RemoveNotificationFromProjectInput{ - NotificationType: api.MicrosoftTeamsNotification, + NotificationType: schema.MicrosoftTeamsNotification, NotificationName: name, Project: cmdProjectName, } @@ -309,16 +307,17 @@ var deleteMicrosoftTeamsNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete Microsoft Teams notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeleteNotificationMicrosoftTeams(context.TODO(), name, lc) if err != nil { @@ -357,25 +356,25 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } - patch := schema.AddNotificationMicrosoftTeamsInput{ - Name: newname, - Webhook: webhook, + patch := schema.UpdateNotificationMicrosoftTeamsPatchInput{ + Name: nullStrCheck(newname), + Webhook: nullStrCheck(webhook), } - b1, _ := json.Marshal(patch) - if bytes.Equal(b1, []byte("{}")) { + if patch == (schema.UpdateNotificationMicrosoftTeamsPatchInput{}) { return fmt.Errorf("missing arguments: either webhook or newname must be defined") } if yesNo(fmt.Sprintf("You are attempting to update Microsoft Teams notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.UpdateNotificationMicrosoftTeamsInput{ diff --git a/cmd/notificationswebhook.go b/cmd/notificationswebhook.go index 86f1100d..58eee15a 100644 --- a/cmd/notificationswebhook.go +++ b/cmd/notificationswebhook.go @@ -1,20 +1,15 @@ package cmd import ( - "bytes" "context" "encoding/json" "fmt" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "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/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) @@ -45,8 +40,8 @@ It does not configure a project to send notifications to webhook though, you nee if err != nil { return err } - if name == "" || webhook == "" { - return fmt.Errorf("missing arguments: name or webhook is not defined") + if err := requiredInputCheck("Notification name", name, "Webhook", webhook); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to create a webhook notification '%s' with webhook url '%s', are you sure?", name, webhook)) { current := lagoonCLIConfig.Current @@ -58,13 +53,13 @@ It does not configure a project to send notifications to webhook though, you nee &token, debug) - notification := s.AddNotificationWebhookInput{ + notification := schema.AddNotificationWebhookInput{ Name: name, Webhook: webhook, Organization: &organizationID, } - result, err := l.AddNotificationWebhook(context.TODO(), ¬ification, lc) + result, err := lagoon.AddNotificationWebhook(context.TODO(), ¬ification, lc) if err != nil { return err } @@ -75,7 +70,7 @@ It does not configure a project to send notifications to webhook though, you nee returnNonEmptyString(fmt.Sprintf("%v", result.Webhook)), } if result.Organization != nil { - organization, err := l.GetOrganizationByID(context.TODO(), organizationID, lc) + organization, err := lagoon.GetOrganizationByID(context.TODO(), organizationID, lc) if err != nil { return err } @@ -116,19 +111,20 @@ This command is used to add an existing webhook notification in Lagoon to a proj if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Notification name", name, "Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to add webhook notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.AddNotificationToProjectInput{ - NotificationType: api.WebhookNotification, + NotificationType: schema.WebhookNotification, NotificationName: name, Project: cmdProjectName, } @@ -170,7 +166,7 @@ var listProjectWebhooksCmd = &cobra.Command{ &token, debug) - result, err := l.GetProjectNotificationWebhook(context.TODO(), cmdProjectName, lc) + result, err := lagoon.GetProjectNotificationWebhook(context.TODO(), cmdProjectName, lc) if err != nil { return err } @@ -213,11 +209,12 @@ var listAllWebhooksCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.GetAllNotificationWebhook(context.TODO(), lc) if err != nil { @@ -264,19 +261,20 @@ var deleteProjectWebhookNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: project name or notification name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete webhook notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.RemoveNotificationFromProjectInput{ - NotificationType: api.WebhookNotification, + NotificationType: schema.WebhookNotification, NotificationName: name, Project: cmdProjectName, } @@ -309,16 +307,17 @@ var deleteWebhookNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete webhook notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.DeleteNotificationWebhook(context.TODO(), name, lc) if err != nil { @@ -357,25 +356,25 @@ var updateWebhookNotificationCmd = &cobra.Command{ if err != nil { return err } - if name == "" { - return fmt.Errorf("missing arguments: notification name is not defined") + if err := requiredInputCheck("Notification name", name); err != nil { + return err } - patch := schema.AddNotificationWebhookInput{ - Name: newname, - Webhook: webhook, + patch := schema.UpdateNotificationWebhookPatchInput{ + Name: nullStrCheck(newname), + Webhook: nullStrCheck(webhook), } - b1, _ := json.Marshal(patch) - if bytes.Equal(b1, []byte("{}")) { + if patch == (schema.UpdateNotificationWebhookPatchInput{}) { return fmt.Errorf("missing arguments: either webhook or newname must be defined") } if yesNo(fmt.Sprintf("You are attempting to update webhook notification '%s', are you sure?", name)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) notification := &schema.UpdateNotificationWebhookInput{ diff --git a/cmd/organization.go b/cmd/organization.go index b18b60ca..1685a2b9 100644 --- a/cmd/organization.go +++ b/cmd/organization.go @@ -6,9 +6,9 @@ import ( "github.com/spf13/cobra" "github.com/uselagoon/lagoon-cli/pkg/output" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" ) var addOrganizationCmd = &cobra.Command{ @@ -68,7 +68,7 @@ var addOrganizationCmd = &cobra.Command{ &token, debug) - organizationInput := s.AddOrganizationInput{ + organizationInput := schema.AddOrganizationInput{ Name: organizationName, FriendlyName: organizationFriendlyName, Description: organizationDescription, @@ -78,7 +78,7 @@ var addOrganizationCmd = &cobra.Command{ QuotaEnvironment: organizationQuotaEnvironment, QuotaRoute: organizationQuotaRoute, } - org := s.Organization{} + org := schema.Organization{} err = lc.AddOrganization(context.TODO(), &organizationInput, &org) if err != nil { return err @@ -124,7 +124,7 @@ var deleteOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -132,7 +132,7 @@ var deleteOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } if yesNo(fmt.Sprintf("You are attempting to delete organization '%s', are you sure?", organization.Name)) { - _, err := l.DeleteOrganization(context.TODO(), organization.ID, lc) + _, err := lagoon.DeleteOrganization(context.TODO(), organization.ID, lc) if err != nil { return err } @@ -202,14 +202,14 @@ var updateOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } if organization.Name == "" { return fmt.Errorf("error querying organization by name") } - organizationInput := s.UpdateOrganizationPatchInput{ + organizationInput := schema.UpdateOrganizationPatchInput{ Description: nullStrCheck(organizationDescription), FriendlyName: nullStrCheck(organizationFriendlyName), QuotaProject: nullIntCheck(organizationQuotaProject), @@ -218,7 +218,7 @@ var updateOrganizationCmd = &cobra.Command{ QuotaEnvironment: nullIntCheck(organizationQuotaEnvironment), QuotaRoute: nullIntCheck(organizationQuotaRoute), } - result, err := l.UpdateOrganization(context.TODO(), organization.ID, organizationInput, lc) + result, err := lagoon.UpdateOrganization(context.TODO(), organization.ID, organizationInput, lc) if err != nil { return err } diff --git a/cmd/project.go b/cmd/project.go index 19684d74..d4ef7079 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -4,62 +4,55 @@ import ( "context" "encoding/json" "fmt" - "os" "strconv" - l "github.com/uselagoon/machinery/api/lagoon" + "strings" + + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" + "github.com/guregu/null" "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" - "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) -var projectPatch api.ProjectPatch - -var projectAutoIdle int -var projectStorageCalc int -var projectDevelopmentEnvironmentsLimit int -var projectOpenshift int -var projectDeploymentsDisabled int -var factsUi int -var problemsUi int - -func parseProjectFlags(flags pflag.FlagSet) api.ProjectPatch { - configMap := make(map[string]interface{}) - flags.VisitAll(func(f *pflag.Flag) { - if flags.Changed(f.Name) { - configMap[f.Name] = &f.Value - } - }) - jsonStr, _ := json.Marshal(configMap) - parsedFlags := api.ProjectPatch{} - json.Unmarshal(jsonStr, &parsedFlags) - return parsedFlags -} - var deleteProjectCmd = &cobra.Command{ Use: "project", Aliases: []string{"p"}, Short: "Delete a project", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project 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") + if err != nil { + return err + } + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + if yesNo(fmt.Sprintf("You are attempting to delete project '%s', are you sure?", cmdProjectName)) { - deleteResult, err := pClient.DeleteProject(cmdProjectName) - handleError(err) + _, err := lagoon.DeleteProject(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } resultData := output.Result{ - Result: string(deleteResult), + Result: "success", } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -85,11 +78,11 @@ var addProjectCmd = &cobra.Command{ if err != nil { return err } - gitUrl, err := cmd.Flags().GetString("gitUrl") + gitUrl, err := cmd.Flags().GetString("git-url") if err != nil { return err } - productionEnvironment, err := cmd.Flags().GetString("productionEnvironment") + productionEnvironment, err := cmd.Flags().GetString("production-environment") if err != nil { return err } @@ -97,7 +90,7 @@ var addProjectCmd = &cobra.Command{ if err != nil { return err } - standbyProductionEnvironment, err := cmd.Flags().GetString("standbyProductionEnvironment") + standbyProductionEnvironment, err := cmd.Flags().GetString("standby-production-environment") if err != nil { return err } @@ -109,19 +102,19 @@ var addProjectCmd = &cobra.Command{ if err != nil { return err } - openshiftProjectPattern, err := cmd.Flags().GetString("openshiftProjectPattern") + openshiftProjectPattern, err := cmd.Flags().GetString("openshift-project-pattern") if err != nil { return err } - developmentEnvironmentsLimit, err := cmd.Flags().GetUint("developmentEnvironmentsLimit") + developmentEnvironmentsLimit, err := cmd.Flags().GetUint("development-environments-limit") if err != nil { return err } - storageCalc, err := cmd.Flags().GetUint("storageCalc") + storageCalc, err := cmd.Flags().GetUint("storage-calc") if err != nil { return err } - autoIdle, err := cmd.Flags().GetUint("autoIdle") + autoIdle, err := cmd.Flags().GetUint("auto-idle") if err != nil { return err } @@ -129,7 +122,11 @@ var addProjectCmd = &cobra.Command{ if err != nil { return err } - privateKey, err := cmd.Flags().GetString("privateKey") + privateKey, err := cmd.Flags().GetString("private-key") + if err != nil { + return err + } + buildImage, err := cmd.Flags().GetString("build-image") if err != nil { return err } @@ -137,12 +134,12 @@ var addProjectCmd = &cobra.Command{ if err != nil { return err } - routerPattern, err := cmd.Flags().GetString("routerPattern") + routerPattern, err := cmd.Flags().GetString("router-pattern") if err != nil { return err } - if err := requiredInputCheck("Project name", cmdProjectName, "GitURL", gitUrl, "Production environment", productionEnvironment, "Openshift", strconv.Itoa(int(openshift))); err != nil { + if err := requiredInputCheck("Project name", cmdProjectName, "git-url", gitUrl, "Production environment", productionEnvironment, "Openshift", strconv.Itoa(int(openshift))); err != nil { return err } @@ -155,7 +152,7 @@ var addProjectCmd = &cobra.Command{ &token, debug) - projectInput := s.AddProjectInput{ + projectInput := schema.AddProjectInput{ Name: cmdProjectName, AddOrgOwner: orgOwner, GitURL: gitUrl, @@ -170,6 +167,7 @@ var addProjectCmd = &cobra.Command{ AutoIdle: autoIdle, Subfolder: subfolder, PrivateKey: privateKey, + BuildImage: buildImage, RouterPattern: routerPattern, } // if organizationid is provided, use it over the name @@ -178,7 +176,7 @@ var addProjectCmd = &cobra.Command{ } // otherwise if name is provided use it if organizationName != "" && organizationID == 0 { - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -190,7 +188,7 @@ var addProjectCmd = &cobra.Command{ projectInput.Organization = organization.ID } - project := s.Project{} + project := schema.Project{} err = lc.AddProject(context.TODO(), &projectInput, &project) if err != nil { return err @@ -214,34 +212,187 @@ var updateProjectCmd = &cobra.Command{ Use: "project", Aliases: []string{"p"}, Short: "Update a project", - Run: func(cmd *cobra.Command, args []string) { - projectFlags := parseProjectFlags(*cmd.Flags()) - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) - } - - var jsonPatchFromProjectFlags string - if string(jsonPatch) != "" { - jsonPatchFromProjectFlags = jsonPatch - } else { - jsonMarshalPatch, _ := json.Marshal(projectFlags) - jsonPatchFromProjectFlags = string(jsonMarshalPatch) - } - - projectUpdateID, err := pClient.UpdateProject(cmdProjectName, jsonPatchFromProjectFlags) - handleError(err) - var updatedProject api.Project - err = json.Unmarshal([]byte(projectUpdateID), &updatedProject) - handleError(err) + 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 + } + projectName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + gitUrl, err := cmd.Flags().GetString("git-url") + if err != nil { + return err + } + productionEnvironment, err := cmd.Flags().GetString("production-environment") + if err != nil { + return err + } + openshift, err := cmd.Flags().GetUint("openshift") + if 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 + } + autoIdleProvided := cmd.Flags().Lookup("auto-idle").Changed + subfolder, err := cmd.Flags().GetString("subfolder") + if err != nil { + return err + } + privateKey, err := cmd.Flags().GetString("private-key") + if err != nil { + return err + } + buildImage, err := cmd.Flags().GetString("build-image") + if err != nil { + return err + } + buildImageProvided := cmd.Flags().Lookup("build-image").Changed + availability, err := cmd.Flags().GetString("availability") + if err != nil { + return err + } + factsUi, err := cmd.Flags().GetUint("facts-ui") + if err != nil { + return err + } + factsUIProvided := cmd.Flags().Lookup("facts-ui").Changed + problemsUi, err := cmd.Flags().GetUint("problems-ui") + if err != nil { + return err + } + problemsUIProvided := cmd.Flags().Lookup("problems-ui").Changed + routerPattern, err := cmd.Flags().GetString("router-pattern") + if err != nil { + return err + } + deploymentsDisabled, err := cmd.Flags().GetUint("deployments-disabled") + if err != nil { + return err + } + deploymentsDisabledProvided := cmd.Flags().Lookup("deployments-disabled").Changed + 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 + } + + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + projectPatch := schema.UpdateProjectPatchInput{ + GitURL: nullStrCheck(gitUrl), + ProductionEnvironment: nullStrCheck(productionEnvironment), + Openshift: nullUintCheck(openshift), + StandbyProductionEnvironment: nullStrCheck(standbyProductionEnvironment), + Branches: nullStrCheck(branches), + Pullrequests: nullStrCheck(pullrequests), + OpenshiftProjectPattern: nullStrCheck(openshiftProjectPattern), + DevelopmentEnvironmentsLimit: nullUintCheck(developmentEnvironmentsLimit), + StorageCalc: nullUintCheck(storageCalc), + AutoIdle: nullUintCheck(autoIdle), + Subfolder: nullStrCheck(subfolder), + PrivateKey: nullStrCheck(privateKey), + FactsUI: nullUintCheck(factsUi), + ProblemsUI: nullUintCheck(problemsUi), + RouterPattern: nullStrCheck(routerPattern), + DeploymentsDisabled: nullUintCheck(deploymentsDisabled), + ProductionBuildPriority: nullUintCheck(ProductionBuildPriority), + DevelopmentBuildPriority: nullUintCheck(DevelopmentBuildPriority), + Name: nullStrCheck(projectName), + } + + if availability != "" { + ProjectAvailability := schema.ProjectAvailability(strings.ToUpper(availability)) + projectPatch.Availability = &ProjectAvailability + } + if autoIdleProvided { + projectPatch.AutoIdle = &autoIdle + } + if deploymentsDisabledProvided { + projectPatch.DeploymentsDisabled = &deploymentsDisabled + } + if factsUIProvided { + projectPatch.FactsUI = &factsUi + } + if problemsUIProvided { + projectPatch.ProblemsUI = &problemsUi + } + if buildImageProvided { + if buildImage == "null" { + nullBuildImage := null.String{} + projectPatch.BuildImage = &nullBuildImage + } else { + buildImg := null.StringFrom(buildImage) + projectPatch.BuildImage = &buildImg + } + } + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + if project.Name == "" { + outputOptions.Error = fmt.Sprintf("Project '%s' not found\n", cmdProjectName) + output.RenderError(outputOptions.Error, outputOptions) + return nil + } + projectUpdate, err := lagoon.UpdateProject(context.TODO(), int(project.ID), projectPatch, lc) + if err != nil { + return err + } + resultData := output.Result{ Result: "success", ResultData: map[string]interface{}{ - "Project Name": updatedProject.Name, + "Project Name": projectUpdate.Name, }, } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -269,8 +420,8 @@ var listProjectByMetadata = &cobra.Command{ if err != nil { return err } - if key == "" { - return fmt.Errorf("missing arguments: key is not defined") + if err := requiredInputCheck("Key", key); err != nil { + return err } current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token @@ -280,7 +431,7 @@ var listProjectByMetadata = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - projects, err := l.GetProjectsByMetadata(context.TODO(), key, value, lc) + projects, err := lagoon.GetProjectsByMetadata(context.TODO(), key, value, lc) if err != nil { return err } @@ -329,17 +480,16 @@ var getProjectMetadata = &cobra.Command{ if err != nil { return err } - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) project, err := lagoon.GetProjectMetadata(context.TODO(), cmdProjectName, lc) if err != nil { @@ -388,8 +538,8 @@ var updateProjectMetadata = &cobra.Command{ if err != nil { return err } - if key == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: Project name or key is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Key", key); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to update key '%s' for project '%s' metadata, are you sure?", key, cmdProjectName)) { current := lagoonCLIConfig.Current @@ -400,11 +550,11 @@ var updateProjectMetadata = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } - projectResult, err := l.UpdateProjectMetadata(context.TODO(), int(project.ID), key, value, lc) + projectResult, err := lagoon.UpdateProjectMetadata(context.TODO(), int(project.ID), key, value, lc) if err != nil { return err } @@ -444,8 +594,8 @@ var deleteProjectMetadataByKey = &cobra.Command{ if err != nil { return err } - if key == "" || cmdProjectName == "" { - return fmt.Errorf("missing arguments: Project name or key is not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Key", key); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to delete key '%s' from project '%s' metadata, are you sure?", key, cmdProjectName)) { current := lagoonCLIConfig.Current @@ -456,11 +606,11 @@ var deleteProjectMetadataByKey = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } - projectResult, err := l.RemoveProjectMetadataByKey(context.TODO(), int(project.ID), key, lc) + projectResult, err := lagoon.RemoveProjectMetadataByKey(context.TODO(), int(project.ID), key, lc) if err != nil { return err } @@ -515,11 +665,11 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ &token, debug) - project, err := l.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { return err } - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -527,13 +677,13 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } - projectInput := s.RemoveProjectFromOrganizationInput{ + projectInput := schema.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) + _, err := lagoon.RemoveProjectFromOrganization(context.TODO(), &projectInput, lc) if err != nil { return err } @@ -554,42 +704,47 @@ func init() { updateProjectCmd.Flags().StringVarP(&jsonPatch, "json", "j", "", "JSON string to patch") // @TODO this seems needlessly busy, maybe see if cobra supports grouping flags and applying them to commands easier? - updateProjectCmd.Flags().StringVarP(&projectPatch.GitURL, "gitUrl", "g", "", "GitURL of the project") - updateProjectCmd.Flags().StringVarP(&projectPatch.PrivateKey, "privateKey", "I", "", "Private key to use for the project") - updateProjectCmd.Flags().StringVarP(&projectPatch.Subfolder, "subfolder", "s", "", "Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository") - updateProjectCmd.Flags().StringVarP(&projectPatch.RouterPattern, "routerPattern", "Z", "", "Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com'") - updateProjectCmd.Flags().StringVarP(&projectPatch.Branches, "branches", "b", "", "Which branches should be deployed") - updateProjectCmd.Flags().StringVarP(&projectPatch.Name, "name", "N", "", "Change the name of the project by specifying a new name (careful!)") - updateProjectCmd.Flags().StringVarP(&projectPatch.Pullrequests, "pullrequests", "m", "", "Which Pull Requests should be deployed") - updateProjectCmd.Flags().StringVarP(&projectPatch.ProductionEnvironment, "productionEnvironment", "E", "", "Which environment(the name) should be marked as the production environment") - updateProjectCmd.Flags().StringVar(&projectPatch.StandbyProductionEnvironment, "standbyProductionEnvironment", "", "Which environment(the name) should be marked as the standby production environment") - updateProjectCmd.Flags().StringVarP(&projectPatch.OpenshiftProjectPattern, "openshiftProjectPattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated") - - updateProjectCmd.Flags().IntVarP(&projectAutoIdle, "autoIdle", "a", 0, "Auto idle setting of the project") - updateProjectCmd.Flags().IntVarP(&projectStorageCalc, "storageCalc", "C", 0, "Should storage for this environment be calculated") - updateProjectCmd.Flags().IntVarP(&projectDevelopmentEnvironmentsLimit, "developmentEnvironmentsLimit", "L", 0, "How many environments can be deployed at one time") - updateProjectCmd.Flags().IntVarP(&projectOpenshift, "openshift", "S", 0, "Reference to OpenShift Object this Project should be deployed to") - updateProjectCmd.Flags().IntVarP(&projectDeploymentsDisabled, "deploymentsDisabled", "", 0, "Admin only flag for disabling deployments on a project, 1 to disable deployments, 0 to enable") - - updateProjectCmd.Flags().IntVarP(&factsUi, "factsUi", "", 0, "Enables the Lagoon insights Facts tab in the UI. Set to 1 to enable, 0 to disable") - updateProjectCmd.Flags().IntVarP(&problemsUi, "problemsUi", "", 0, "Enables the Lagoon insights Problems tab in the UI. Set to 1 to enable, 0 to disable") + updateProjectCmd.Flags().StringP("git-url", "g", "", "GitURL of the project") + updateProjectCmd.Flags().StringP("private-key", "I", "", "Private key to use for the project") + updateProjectCmd.Flags().StringP("subfolder", "s", "", "Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository") + updateProjectCmd.Flags().StringP("router-pattern", "Z", "", "Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com'") + updateProjectCmd.Flags().StringP("branches", "b", "", "Which branches should be deployed") + updateProjectCmd.Flags().StringP("name", "N", "", "Change the name of the project by specifying a new name (careful!)") + updateProjectCmd.Flags().StringP("pullrequests", "m", "", "Which Pull Requests should be deployed") + updateProjectCmd.Flags().StringP("production-environment", "E", "", "Which environment(the name) should be marked as the production environment") + updateProjectCmd.Flags().String("standby-production-environment", "", "Which environment(the name) should be marked as the standby production environment") + updateProjectCmd.Flags().StringP("openshift-project-pattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated") + updateProjectCmd.Flags().StringP("build-image", "", "", "Build Image for the project. Set to 'null' to remove the build image") + updateProjectCmd.Flags().StringP("availability", "", "", "Availability of the project") + + updateProjectCmd.Flags().Uint("production-build-priority", 0, "Set the priority of the production build") + updateProjectCmd.Flags().Uint("development-build-priority", 0, "Set the priority of the development build") + updateProjectCmd.Flags().UintP("auto-idle", "a", 0, "Auto idle setting of the project") + updateProjectCmd.Flags().UintP("storage-calc", "C", 0, "Should storage for this environment be calculated") + updateProjectCmd.Flags().UintP("development-environments-limit", "L", 0, "How many environments can be deployed at one time") + updateProjectCmd.Flags().UintP("openshift", "S", 0, "Reference to OpenShift Object this Project should be deployed to") + updateProjectCmd.Flags().UintP("deployments-disabled", "", 0, "Admin only flag for disabling deployments on a project, 1 to disable deployments, 0 to enable") + + updateProjectCmd.Flags().UintP("facts-ui", "", 0, "Enables the Lagoon insights Facts tab in the UI. Set to 1 to enable, 0 to disable") + updateProjectCmd.Flags().UintP("problems-ui", "", 0, "Enables the Lagoon insights Problems tab in the UI. Set to 1 to enable, 0 to disable") addProjectCmd.Flags().StringP("json", "j", "", "JSON string to patch") - addProjectCmd.Flags().StringP("gitUrl", "g", "", "GitURL of the project") - addProjectCmd.Flags().StringP("privateKey", "I", "", "Private key to use for the project") + addProjectCmd.Flags().StringP("git-url", "g", "", "GitURL of the project") + addProjectCmd.Flags().StringP("private-key", "I", "", "Private key to use for the project") addProjectCmd.Flags().StringP("subfolder", "s", "", "Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository") - addProjectCmd.Flags().StringP("routerPattern", "Z", "", "Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com'") + addProjectCmd.Flags().StringP("router-pattern", "Z", "", "Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com'") addProjectCmd.Flags().StringP("branches", "b", "", "Which branches should be deployed") addProjectCmd.Flags().StringP("pullrequests", "m", "", "Which Pull Requests should be deployed") - addProjectCmd.Flags().StringP("productionEnvironment", "E", "", "Which environment(the name) should be marked as the production environment") - addProjectCmd.Flags().String("standbyProductionEnvironment", "", "Which environment(the name) should be marked as the standby production environment") - addProjectCmd.Flags().StringP("openshiftProjectPattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated") + addProjectCmd.Flags().StringP("production-environment", "E", "", "Which environment(the name) should be marked as the production environment") + addProjectCmd.Flags().String("standby-production-environment", "", "Which environment(the name) should be marked as the standby production environment") + addProjectCmd.Flags().StringP("openshift-project-pattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated") - addProjectCmd.Flags().UintP("autoIdle", "a", 0, "Auto idle setting of the project") - addProjectCmd.Flags().UintP("storageCalc", "C", 0, "Should storage for this environment be calculated") - addProjectCmd.Flags().UintP("developmentEnvironmentsLimit", "L", 0, "How many environments can be deployed at one time") + addProjectCmd.Flags().UintP("auto-idle", "a", 0, "Auto idle setting of the project") + addProjectCmd.Flags().UintP("storage-calc", "C", 0, "Should storage for this environment be calculated") + addProjectCmd.Flags().UintP("development-environments-limit", "L", 0, "How many environments can be deployed at one time") addProjectCmd.Flags().UintP("openshift", "S", 0, "Reference to OpenShift Object this Project should be deployed to") + addProjectCmd.Flags().StringP("build-image", "", "", "Build Image for the project") addProjectCmd.Flags().Bool("owner", false, "Add the user as an owner of the project") addProjectCmd.Flags().StringP("organization-name", "O", "", "Name of the Organization to add the project to") addProjectCmd.Flags().UintP("organization-id", "", 0, "ID of the Organization to add the project to") diff --git a/cmd/retrieve.go b/cmd/retrieve.go index 40ef3498..eec279bb 100644 --- a/cmd/retrieve.go +++ b/cmd/retrieve.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" + "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" ) var retrieveCmd = &cobra.Command{ @@ -39,16 +39,17 @@ You can check the status of the backup using the list backups or get backup comm if err != nil { return err } - if backupID == "" { - return fmt.Errorf("missing arguments: backup-id is not defined") + if err := requiredInputCheck("Backup ID", backupID); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to trigger a retrieval for backup ID '%s', are you sure?", backupID)) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) result, err := lagoon.AddBackupRestore(context.TODO(), backupID, lc) if err != nil { diff --git a/cmd/root.go b/cmd/root.go index a6ba8492..0c0254e8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,16 +10,13 @@ import ( "strings" "time" + "github.com/golang-jwt/jwt" "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" lagooncli "github.com/uselagoon/lagoon-cli/internal/lagoon" "github.com/uselagoon/lagoon-cli/internal/lagoon/client" "github.com/uselagoon/lagoon-cli/pkg/app" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/lagoon/environments" - "github.com/uselagoon/lagoon-cli/pkg/lagoon/projects" - "github.com/uselagoon/lagoon-cli/pkg/lagoon/users" "github.com/uselagoon/lagoon-cli/pkg/output" "github.com/uselagoon/lagoon-cli/pkg/updatecheck" ) @@ -284,11 +281,6 @@ func Prompt(prompt string) string { return GetInput() } -// global the clients -var eClient environments.Client -var uClient users.Client -var pClient projects.Client - // FormatType . type FormatType string @@ -305,7 +297,7 @@ func validateToken(lagoon string) { fmt.Println(err) os.Exit(1) } - valid := graphql.VerifyTokenExpiry(&lagoonCLIConfig, lagoon) + valid := VerifyTokenExpiry(&lagoonCLIConfig, lagoon) if !valid { loginErr := loginToken() if loginErr != nil { @@ -313,22 +305,6 @@ func validateToken(lagoon string) { os.Exit(1) } } - // set up the clients - eClient, err = environments.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - uClient, err = users.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - pClient, err = projects.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } outputOptions.Debug = debugEnable } @@ -339,7 +315,7 @@ func validateTokenE(lagoon string) error { if err = checkContextExists(&lagoonCLIConfig); err != nil { return err } - if graphql.VerifyTokenExpiry(&lagoonCLIConfig, lagoon) { + if VerifyTokenExpiry(&lagoonCLIConfig, lagoon) { // check the API for the version of lagoon if we haven't got one set // otherwise return nil, nothing to do return nil @@ -347,22 +323,6 @@ func validateTokenE(lagoon string) error { if err = loginToken(); err != nil { return fmt.Errorf("couldn't refresh token: %w", err) } - // set up the clients - eClient, err = environments.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - return err - } - uClient, err = users.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - return err - } - pClient, err = projects.New(&lagoonCLIConfig, debugEnable) - if err != nil { - output.RenderError(err.Error(), outputOptions) - return err - } outputOptions.Debug = debugEnable // fallback if token is expired or there was no token to begin with return nil @@ -462,3 +422,17 @@ func checkContextExists(lagoonCLIConfig *lagooncli.Config) error { } return nil } + +// VerifyTokenExpiry verfies if the current token is valid or not +func VerifyTokenExpiry(lc *lagooncli.Config, lagoon string) bool { + var p jwt.Parser + token, _, err := p.ParseUnverified( + lc.Lagoons[lagoon].Token, &jwt.StandardClaims{}) + if err != nil { + return false + } + if token.Claims.Valid() != nil { + return false + } + return true +} diff --git a/cmd/shared.go b/cmd/shared.go index 1d28cbc3..2cc479d1 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -17,14 +17,6 @@ var lagoonUI string var lagoonKibana string var lagoonSSHKey string -// user vars -var userFirstName string -var userLastName string -var userEmail string -var resetPassword bool -var pubKeyFile string -var sshKeyName string - // group vars var groupName string @@ -44,6 +36,8 @@ var outputOptions = output.Options{ Debug: false, } +var groupRoles = []string{"guest", "reporter", "developer", "maintainer", "owner"} + var debugEnable bool func handleError(err error) { diff --git a/cmd/ssh.go b/cmd/ssh.go index f8740532..1a406a25 100644 --- a/cmd/ssh.go +++ b/cmd/ssh.go @@ -5,9 +5,10 @@ import ( "fmt" "os" + "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" lagoonssh "github.com/uselagoon/lagoon-cli/pkg/lagoon/ssh" "github.com/uselagoon/lagoon-cli/pkg/output" "golang.org/x/crypto/ssh" @@ -21,11 +22,12 @@ var sshEnvCmd = &cobra.Command{ Use: "ssh", Aliases: []string{"s"}, Short: "Display the SSH command to access a specific environment in a project", + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, RunE: func(cmd *cobra.Command, args []string) error { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid - - if cmdProjectName == "" || cmdProjectEnvironment == "" { - return fmt.Errorf("missing arguments: Project name or environment name are not defined") + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err } debug, err := cmd.Flags().GetBool("debug") if err != nil { @@ -44,11 +46,12 @@ var sshEnvCmd = &cobra.Command{ isPortal := false // if the config for this lagoon is set to use ssh portal support, handle that here - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) project, err := lagoon.GetSSHEndpointsByProject(context.TODO(), cmdProjectName, lc) if err != nil { diff --git a/cmd/tasks.go b/cmd/tasks.go index df7de11e..3b28c0e4 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -7,14 +7,15 @@ import ( "errors" "fmt" "os" + "strconv" "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" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" + "github.com/uselagoon/machinery/api/schema" ) var getTaskByID = &cobra.Command{ @@ -39,8 +40,8 @@ var getTaskByID = &cobra.Command{ if err != nil { return err } - if taskID == 0 { - return fmt.Errorf("missing arguments: ID is not defined") + if err := requiredInputCheck("ID", strconv.Itoa(taskID)); err != nil { + return err } current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token @@ -50,7 +51,7 @@ var getTaskByID = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - result, err := l.TaskByID(context.TODO(), taskID, lc) + result, err := lagoon.TaskByID(context.TODO(), taskID, lc) if err != nil { return err } @@ -98,8 +99,8 @@ If the task fails or fails to update, contact your Lagoon administrator for assi if err != nil { return err } - if cmdProjectName == "" { - return fmt.Errorf("missing arguments: Project name is not defined") + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } if yesNo(fmt.Sprintf("You are attempting to run the active/standby switch for project '%s', are you sure?", cmdProjectName)) { current := lagoonCLIConfig.Current @@ -110,13 +111,11 @@ If the task fails or fails to update, contact your Lagoon administrator for assi lagoonCLIConfig.Lagoons[current].Version, &token, debug) - result, err := l.ActiveStandbySwitch(context.TODO(), cmdProjectName, lc) + result, err := lagoon.ActiveStandbySwitch(context.TODO(), cmdProjectName, lc) if err != nil { return err } - fmt.Printf(`Created a new task with ID %d -You can use the following command to query the task status: -lagoon -l %s get task-by-id --id %d --logs\n`, result.ID, current, result.ID) + fmt.Printf("Created a new task with ID %d \nYou can use the following command to query the task status: \nlagoon -l %s get task-by-id --id %d --logs \n", result.ID, current, result.ID) } return nil }, @@ -126,22 +125,67 @@ var runDrushArchiveDump = &cobra.Command{ Use: "drush-archivedump", Aliases: []string{"dard"}, Short: "Run a drush archive dump on an environment", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name are not defined") - cmd.Help() - os.Exit(1) - } - taskResult, err := eClient.RunDrushArchiveDump(cmdProjectName, cmdProjectEnvironment) - handleError(err) + 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 err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + if err != nil { + return err + } + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + raw := `mutation runArdTask ($environment: Int!) { + taskDrushArchiveDump(environment: $environment) { + id + } + }` + rawResp, err := lc.ProcessRaw(context.TODO(), raw, map[string]interface{}{ + "environment": environment.ID, + }) + if err != nil { + return err + } + r, err := json.Marshal(rawResp) + if err != nil { + return err + } var resultMap map[string]interface{} - err = json.Unmarshal([]byte(taskResult), &resultMap) - handleError(err) - resultData := output.Result{ - Result: "success", - ResultData: resultMap, + err = json.Unmarshal([]byte(r), &resultMap) + if err != nil { + return err } - output.RenderResult(resultData, outputOptions) + if resultMap["taskDrushArchiveDump"] != nil { + resultData := output.Result{ + Result: "success", + ResultData: resultMap["taskDrushArchiveDump"].(map[string]interface{}), + } + output.RenderResult(resultData, outputOptions) + } else { + return fmt.Errorf("unable to determine status of task") + } + return nil }, } @@ -149,22 +193,67 @@ var runDrushSQLDump = &cobra.Command{ Use: "drush-sqldump", Aliases: []string{"dsqld"}, Short: "Run a drush sql dump on an environment", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name are not defined") - cmd.Help() - os.Exit(1) - } - taskResult, err := eClient.RunDrushSQLDump(cmdProjectName, cmdProjectEnvironment) - handleError(err) + 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 err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + if err != nil { + return err + } + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + raw := `mutation runSqlDump ($environment: Int!) { + taskDrushSqlDump(environment: $environment) { + id + } + }` + rawResp, err := lc.ProcessRaw(context.TODO(), raw, map[string]interface{}{ + "environment": environment.ID, + }) + if err != nil { + return err + } + r, err := json.Marshal(rawResp) + if err != nil { + return err + } var resultMap map[string]interface{} - err = json.Unmarshal([]byte(taskResult), &resultMap) - handleError(err) - resultData := output.Result{ - Result: "success", - ResultData: resultMap, + err = json.Unmarshal([]byte(r), &resultMap) + if err != nil { + return err } - output.RenderResult(resultData, outputOptions) + if resultMap["taskDrushSqlDump"] != nil { + resultData := output.Result{ + Result: "success", + ResultData: resultMap["taskDrushSqlDump"].(map[string]interface{}), + } + output.RenderResult(resultData, outputOptions) + } else { + return fmt.Errorf("unable to determine status of task") + } + return nil }, } @@ -172,51 +261,135 @@ var runDrushCacheClear = &cobra.Command{ Use: "drush-cacheclear", Aliases: []string{"dcc"}, Short: "Run a drush cache clear on an environment", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" { - fmt.Println("Missing arguments: Project name or environment name are not defined") - cmd.Help() - os.Exit(1) - } - taskResult, err := eClient.RunDrushCacheClear(cmdProjectName, cmdProjectEnvironment) - handleError(err) + 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 err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { + return err + } + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + if err != nil { + return err + } + + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + raw := `mutation runCacheClear ($environment: Int!) { + taskDrushCacheClear(environment: $environment) { + id + } + }` + rawResp, err := lc.ProcessRaw(context.TODO(), raw, map[string]interface{}{ + "environment": environment.ID, + }) + if err != nil { + return err + } + r, err := json.Marshal(rawResp) + if err != nil { + return err + } var resultMap map[string]interface{} - err = json.Unmarshal([]byte(taskResult), &resultMap) - handleError(err) - resultData := output.Result{ - Result: "success", - ResultData: resultMap, + err = json.Unmarshal([]byte(r), &resultMap) + if err != nil { + return err } - output.RenderResult(resultData, outputOptions) + if resultMap["taskDrushCacheClear"] != nil { + resultData := output.Result{ + Result: "success", + ResultData: resultMap["taskDrushCacheClear"].(map[string]interface{}), + } + output.RenderResult(resultData, outputOptions) + } else { + return fmt.Errorf("unable to determine status of task") + } + return nil }, } var invokeDefinedTask = &cobra.Command{ Use: "invoke", Aliases: []string{"i"}, - Short: "", + Short: "Invoke a task registered against an environment", Long: `Invoke a task registered against an environment The following are supported methods to use Direct: lagoon run invoke -p example -e main -N "advanced task name" `, - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" || cmdProjectEnvironment == "" || invokedTaskName == "" { - fmt.Println("Missing arguments: Project name, environment name, or task command are not defined") - cmd.Help() - os.Exit(1) + 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 + } + invokedTaskName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment, "Task command", invokedTaskName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetAdvancedTasksByEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) + if err != nil { + return err + } + + var taskId uint + for _, task := range environment.AdvancedTasks { + if invokedTaskName == task.Name { + taskId = uint(task.ID) + } + } + + taskResult, err := lagoon.InvokeAdvancedTaskDefinition(context.TODO(), environment.ID, taskId, lc) + if err != nil { + return err } - taskResult, err := eClient.InvokeAdvancedTaskDefinition(cmdProjectName, cmdProjectEnvironment, invokedTaskName) - handleError(err) - var resultMap map[string]interface{} - err = json.Unmarshal([]byte(taskResult), &resultMap) - handleError(err) resultData := output.Result{ - Result: "success", - ResultData: resultMap, + Result: "success", + ResultData: map[string]interface{}{ + "id": taskResult.ID, + "name": taskResult.Name, + "status": taskResult.Status, + }, } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -235,7 +408,30 @@ STDIN: Path: lagoon run custom -p example -e main -N "My Task" -S cli -s /path/to/my-script.sh `, - Run: func(cmd *cobra.Command, args []string) { + 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 + } + taskName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + taskService, err := cmd.Flags().GetString("service") + if err != nil { + return err + } + taskCommand, err := cmd.Flags().GetString("command") + if err != nil { + return err + } + taskCommandFile, err := cmd.Flags().GetString("script") + if err != nil { + return err + } stat, _ := os.Stdin.Stat() if (stat.Mode() & os.ModeCharDevice) == 0 { // check if we are getting data froms stdin @@ -245,38 +441,56 @@ Path: taskCommand = taskCommand + scanner.Text() + "\n" } if err := scanner.Err(); err != nil { - // fmt.Fprintln(os.Stderr, "reading standard input:", err) handleError(errors.New("reading standard input:" + err.Error())) } } else { // otherwise we can read from a file if taskCommandFile != "" { taskCommandBytes, err := os.ReadFile(taskCommandFile) // just pass the file name - handleError(err) + if err != nil { + return err + } taskCommand = string(taskCommandBytes) } } - if cmdProjectName == "" || cmdProjectEnvironment == "" || taskCommand == "" { - fmt.Println("Missing arguments: Project name, environment name, or task command are not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment, "Task command", taskCommand, "Task name", taskName, "Task service", taskService); err != nil { + return err } - task := api.Task{ + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + task := schema.Task{ Name: taskName, Command: taskCommand, Service: taskService, } - taskResult, err := eClient.RunCustomTask(cmdProjectName, cmdProjectEnvironment, task) - handleError(err) - var resultMap map[string]interface{} - err = json.Unmarshal([]byte(taskResult), &resultMap) - handleError(err) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + return err + } + environment, err := lagoon.GetEnvironmentByName(context.TODO(), cmdProjectEnvironment, project.ID, lc) + if err != nil { + return err + } + taskResult, err := lagoon.AddTask(context.TODO(), environment.ID, task, lc) + if err != nil { + return err + } resultData := output.Result{ - Result: "success", - ResultData: resultMap, + Result: "success", + ResultData: map[string]interface{}{ + "id": taskResult.ID, + }, } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -298,8 +512,8 @@ var uploadFilesToTask = &cobra.Command{ if err != nil { return err } - if taskID == 0 { - return fmt.Errorf("missing arguments: ID is not defined") + if err := requiredInputCheck("ID", strconv.Itoa(taskID)); err != nil { + return err } files, err := cmd.Flags().GetStringSlice("file") if err != nil { @@ -313,7 +527,7 @@ var uploadFilesToTask = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - result, err := l.UploadFilesForTask(context.TODO(), taskID, files, lc) + result, err := lagoon.UploadFilesForTask(context.TODO(), taskID, files, lc) if err != nil { return err } @@ -340,20 +554,12 @@ var uploadFilesToTask = &cobra.Command{ }, } -var ( - taskName string - invokedTaskName string - taskService string - taskCommand string - taskCommandFile string -) - 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)") - runCustomTask.Flags().StringVarP(&taskCommand, "command", "c", "", "The command to run in the task") - runCustomTask.Flags().StringVarP(&taskCommandFile, "script", "s", "", "Path to bash script to run (will use this before command(-c) if both are defined)") + invokeDefinedTask.Flags().StringP("name", "N", "", "Name of the task that will be invoked") + runCustomTask.Flags().StringP("name", "N", "Custom Task", "Name of the task that will show in the UI (default: Custom Task)") + runCustomTask.Flags().StringP("service", "S", "cli", "Name of the service (cli, nginx, other) that should run the task (default: cli)") + runCustomTask.Flags().StringP("command", "c", "", "The command to run in the task") + runCustomTask.Flags().StringP("script", "s", "", "Path to bash script to run (will use this before command(-c) if both are defined)") } diff --git a/cmd/users.go b/cmd/users.go index 28c90ba8..4947e945 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -2,38 +2,20 @@ package cmd import ( "context" - "encoding/json" "fmt" "os" "strconv" "strings" - l "github.com/uselagoon/machinery/api/lagoon" + "github.com/uselagoon/machinery/api/lagoon" lclient "github.com/uselagoon/machinery/api/lagoon/client" - s "github.com/uselagoon/machinery/api/schema" + "github.com/uselagoon/machinery/api/schema" "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" ) -func parseUser(flags pflag.FlagSet) api.User { - configMap := make(map[string]interface{}) - flags.VisitAll(func(f *pflag.Flag) { - if flags.Changed(f.Name) { - configMap[f.Name] = f.Value - } - }) - jsonStr, _ := json.Marshal(configMap) - parsedFlags := api.User{} - json.Unmarshal(jsonStr, &parsedFlags) - // lowercase user email address - parsedFlags.Email = strings.ToLower(parsedFlags.Email) - return parsedFlags -} - -func parseSSHKeyFile(sshPubKey string, keyName string, keyValue string, userEmail string) (api.SSHKey, error) { +func parseSSHKeyFile(sshPubKey string, keyName string, keyValue string, userEmail string) (schema.AddSSHKeyInput, error) { // if we haven't got a keyvalue if keyValue == "" { b, err := os.ReadFile(sshPubKey) // just pass the file name @@ -41,24 +23,24 @@ func parseSSHKeyFile(sshPubKey string, keyName string, keyValue string, userEmai keyValue = string(b) } splitKey := strings.Split(keyValue, " ") - var keyType api.SSHKeyType + var keyType schema.SSHKeyType var err error // will fail if value is not right if strings.EqualFold(string(splitKey[0]), "ssh-rsa") { - keyType = api.SSHRsa + keyType = schema.SSHRsa } else if strings.EqualFold(string(splitKey[0]), "ssh-ed25519") { - keyType = api.SSHEd25519 + keyType = schema.SSHEd25519 } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp256") { - keyType = api.SSHECDSA256 + keyType = schema.SSHECDSA256 } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp384") { - keyType = api.SSHECDSA384 + keyType = schema.SSHECDSA384 } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp521") { - keyType = api.SSHECDSA521 + keyType = schema.SSHECDSA521 } else { // return error stating key type not supported - keyType = api.SSHRsa - err = fmt.Errorf(fmt.Sprintf("SSH key type %s not supported", string(splitKey[0]))) + keyType = schema.SSHRsa + err = fmt.Errorf(fmt.Sprintf("SSH key type %s not supported", splitKey[0])) } // if the sshkey has a comment/name in it, we can use that @@ -69,37 +51,78 @@ func parseSSHKeyFile(sshPubKey string, keyName string, keyValue string, userEmai keyName = userEmail output.RenderInfo("no name provided, using email address as key name", outputOptions) } - parsedFlags := api.SSHKey{ - KeyType: keyType, - KeyValue: stripNewLines(splitKey[1]), - Name: keyName, + SSHKeyInput := schema.AddSSHKeyInput{ + SSHKey: schema.SSHKey{ + KeyType: keyType, + KeyValue: stripNewLines(splitKey[1]), + Name: keyName, + }, + UserEmail: userEmail, } - return parsedFlags, err + + return SSHKeyInput, err } var addUserCmd = &cobra.Command{ Use: "user", Aliases: []string{"u"}, Short: "Add a user to lagoon", - Run: func(cmd *cobra.Command, args []string) { - user := parseUser(*cmd.Flags()) - if user.Email == "" { - fmt.Println("Missing arguments: Email address 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") + if err != nil { + return err } - var customReqResult []byte - var err error - customReqResult, err = uClient.AddUser(user, resetPassword) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + firstName, err := cmd.Flags().GetString("first-name") + if err != nil { + return err + } + LastName, err := cmd.Flags().GetString("last-name") + if err != nil { + return err + } + email, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + resetPassword, err := cmd.Flags().GetBool("reset-password") + if err != nil { + return err + } + if err := requiredInputCheck("Email address", email); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + userInput := &schema.AddUserInput{ + FirstName: firstName, + LastName: LastName, + Email: email, + ResetPassword: resetPassword, + } + user, err := lagoon.AddUser(context.TODO(), userInput, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", + ResultData: map[string]interface{}{ + "id": user.ID, + }, } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -123,33 +146,67 @@ Add key by defining key value, but not specifying a key name (will default to tr lagoon add user-sshkey --email test@example.com --keyvalue "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINA0ITV2gbDc6noYeWaqfxTYpaEKq7HzU3+F71XGhSL/" `, - Run: func(cmd *cobra.Command, args []string) { - userFlags := parseUser(*cmd.Flags()) - if userFlags.Email == "" { - fmt.Println("Missing arguments: Email address 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") + if err != nil { + return err } - var err error - userSSHKey, err := parseSSHKeyFile(pubKeyFile, sshKeyName, pubKeyValue, userFlags.Email) - handleError(err) - var customReqResult []byte - customReqResult, err = uClient.AddSSHKeyToUser(userFlags, userSSHKey) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + pubKeyFile, err := cmd.Flags().GetString("pubkey") + if err != nil { + return err + } + sshKeyName, err := cmd.Flags().GetString("keyname") + if err != nil { + return err + } + pubKeyValue, err := cmd.Flags().GetString("keyvalue") + if err != nil { + return err + } + email, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + + if err := requiredInputCheck("Email address", email); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + userSSHKey, err := parseSSHKeyFile(pubKeyFile, sshKeyName, pubKeyValue, email) + if err != nil { + return err + } + result, err := lagoon.AddSSHKey(context.TODO(), &userSSHKey, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", + ResultData: map[string]interface{}{ + "ID": result.ID, + }, } output.RenderResult(resultData, outputOptions) + return nil }, } var deleteSSHKeyCmd = &cobra.Command{ Use: "user-sshkey", - Aliases: []string{"u"}, + Aliases: []string{"uk"}, Short: "Delete an SSH key from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { return validateTokenE(cmdLagoon) @@ -163,10 +220,10 @@ var deleteSSHKeyCmd = &cobra.Command{ if err != nil { return err } - if sshKeyID == 0 { - fmt.Println("Missing arguments: SSH key ID is not defined") - return nil + if err := requiredInputCheck("SSH key ID", strconv.Itoa(int(sshKeyID))); err != nil { + return err } + current := lagoonCLIConfig.Current token := lagoonCLIConfig.Lagoons[current].Token lc := lclient.New( @@ -177,8 +234,10 @@ var deleteSSHKeyCmd = &cobra.Command{ 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) + _, err := lagoon.RemoveSSHKey(context.TODO(), sshKeyID, lc) + if err != nil { + return err + } resultData := output.Result{ Result: "success", } @@ -192,23 +251,45 @@ var deleteUserCmd = &cobra.Command{ Use: "user", Aliases: []string{"u"}, Short: "Delete a user from Lagoon", - Run: func(cmd *cobra.Command, args []string) { - userFlags := parseUser(*cmd.Flags()) - if userFlags.Email == "" { - fmt.Println("Missing arguments: Email address 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") + if err != nil { + return err } - var customReqResult []byte - var err error - if yesNo(fmt.Sprintf("You are attempting to delete user with email address '%s', are you sure?", userFlags.Email)) { - customReqResult, err = uClient.DeleteUser(userFlags) - handleError(err) + emailAddress, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + if err := requiredInputCheck("Email address", emailAddress); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + deleteUserInput := &schema.DeleteUserInput{ + User: schema.UserInput{Email: emailAddress}, + } + if yesNo(fmt.Sprintf("You are attempting to delete user with email address '%s', are you sure?", emailAddress)) { + _, err := lagoon.DeleteUser(context.TODO(), deleteUserInput, lc) + if err != nil { + return err + } resultData := output.Result{ - Result: string(customReqResult), + Result: "success", } output.RenderResult(resultData, outputOptions) } + return nil }, } @@ -217,28 +298,72 @@ var updateUserCmd = &cobra.Command{ Aliases: []string{"u"}, Short: "Update a user in Lagoon", Long: "Update a user in Lagoon (change name, or email address)", - Run: func(cmd *cobra.Command, args []string) { - userFlags := parseUser(*cmd.Flags()) - if userFlags.Email == "" { - fmt.Println("Missing arguments: Email address is not defined") + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(cmdLagoon) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err + } + emailAddress, err := cmd.Flags().GetString("email") + if err != nil { + return err + } + firstName, err := cmd.Flags().GetString("first-name") + if err != nil { + return err + } + lastName, err := cmd.Flags().GetString("last-name") + if err != nil { + return err + } + currentEmail, err := cmd.Flags().GetString("current-email") + if err != nil { + return err + } + if err := requiredInputCheck("Current email address", currentEmail); err != nil { + return err + } + if firstName == "" && lastName == "" && emailAddress == "" { cmd.Help() - os.Exit(1) + output.RenderError("Missing arguments: Nothing to update, please provide a field to update", outputOptions) + return nil } - var customReqResult []byte - var err error - currentUser := api.User{ - Email: strings.ToLower(currentUserEmail), + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + currentUser := &schema.UpdateUserInput{ + User: schema.UserInput{ + Email: strings.ToLower(currentEmail), + }, + Patch: schema.UpdateUserPatchInput{ + Email: nullStrCheck(strings.ToLower(emailAddress)), + FirstName: nullStrCheck(firstName), + LastName: nullStrCheck(lastName), + }, } - customReqResult, err = uClient.ModifyUser(currentUser, userFlags) - handleError(err) - returnResultData := map[string]interface{}{} - err = json.Unmarshal([]byte(customReqResult), &returnResultData) - handleError(err) + + user, err := lagoon.UpdateUser(context.TODO(), currentUser, lc) + if err != nil { + return err + } + resultData := output.Result{ - Result: "success", - ResultData: returnResultData, + Result: "success", + ResultData: map[string]interface{}{ + "ID": user.ID, + }, } output.RenderResult(resultData, outputOptions) + return nil }, } @@ -260,9 +385,8 @@ var getUserKeysCmd = &cobra.Command{ if err != nil { return err } - if userEmail == "" { - fmt.Println("Missing arguments: Email address is not defined") - return nil + if err := requiredInputCheck("Email address", userEmail); err != nil { + return err } current := lagoonCLIConfig.Current @@ -273,8 +397,10 @@ var getUserKeysCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - userKeys, err := l.GetUserSSHKeysByEmail(context.TODO(), userEmail, lc) - handleError(err) + userKeys, err := lagoon.GetUserSSHKeysByEmail(context.TODO(), userEmail, lc) + if err != nil { + return err + } if len(userKeys.SSHKeys) == 0 { output.RenderInfo(fmt.Sprintf("No SSH keys for user '%s'", strings.ToLower(userEmail)), outputOptions) return nil @@ -328,18 +454,22 @@ var getAllUserKeysCmd = &cobra.Command{ lagoonCLIConfig.Lagoons[current].Version, &token, debug) - groupMembers, err := l.ListAllGroupMembersWithKeys(context.TODO(), groupName, lc) - handleError(err) + groupMembers, err := lagoon.ListAllGroupMembersWithKeys(context.TODO(), groupName, lc) + if err != nil { + return err + } - var userGroups []s.AddSSHKeyInput + var userGroups []schema.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}) + userGroups = append(userGroups, schema.AddSSHKeyInput{SSHKey: key, UserEmail: member.User.Email}) } } } - + if len(userGroups) == 0 { + outputOptions.Error = fmt.Sprintf("No SSH keys for group '%s'\n", groupName) + } var data []output.Data for _, userData := range userGroups { keyID := strconv.Itoa(int(userData.SSHKey.ID)) @@ -405,7 +535,7 @@ var addAdministratorToOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -413,13 +543,13 @@ var addAdministratorToOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } - userInput := s.AddUserToOrganizationInput{ - User: s.UserInput{Email: userEmail}, + userInput := schema.AddUserToOrganizationInput{ + User: schema.UserInput{Email: userEmail}, Organization: organization.ID, Owner: owner, } - orgUser := s.Organization{} + orgUser := schema.Organization{} err = lc.AddUserToOrganization(context.TODO(), &userInput, &orgUser) if err != nil { return err @@ -478,7 +608,7 @@ var removeAdministratorFromOrganizationCmd = &cobra.Command{ &token, debug) - organization, err := l.GetOrganizationByName(context.TODO(), organizationName, lc) + organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { return err } @@ -486,19 +616,17 @@ var removeAdministratorFromOrganizationCmd = &cobra.Command{ return fmt.Errorf("error querying organization by name") } - userInput := s.AddUserToOrganizationInput{ - User: s.UserInput{Email: userEmail}, + userInput := schema.AddUserToOrganizationInput{ + User: schema.UserInput{Email: userEmail}, Organization: organization.ID, Owner: owner, } - orgUser := s.Organization{} + orgUser := schema.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) - if err != nil { - return err - } + handleError(err) resultData := output.Result{ Result: "success", ResultData: map[string]interface{}{ @@ -516,44 +644,64 @@ var resetPasswordCmd = &cobra.Command{ Use: "reset-password", Aliases: []string{"reset-pass", "rp"}, Short: "Send a password reset email", - PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) }, - Run: func(cmd *cobra.Command, args []string) { - if userEmail == "" { - fmt.Println("Missing arguments: Email address is not defined") - cmd.Help() - os.Exit(1) + 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 err := requiredInputCheck("Email address", userEmail); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + resetPasswordInput := schema.ResetUserPasswordInput{ + User: schema.UserInput{Email: userEmail}, } if yesNo(fmt.Sprintf("You are attempting to send a password reset email to '%s', are you sure?", userEmail)) { - result, err := uClient.ResetPassword(userEmail) - handleError(err) - fmt.Println(string(result)) + _, err := lagoon.ResetUserPassword(context.TODO(), &resetPasswordInput, lc) + if err != nil { + return err + } + resultData := output.Result{ + Result: "success", + } + output.RenderResult(resultData, outputOptions) } + return nil }, } -var ( - currentUserEmail string - pubKeyValue string -) - func init() { - addUserCmd.Flags().StringVarP(&userFirstName, "firstName", "F", "", "First name of the user") - addUserCmd.Flags().StringVarP(&userLastName, "lastName", "L", "", "Last name of the user") - addUserCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") - addUserCmd.Flags().BoolVarP(&resetPassword, "reset-password", "", false, "Send a password reset email") - addUserSSHKeyCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") - addUserSSHKeyCmd.Flags().StringVarP(&sshKeyName, "keyname", "N", "", "Name of the SSH key (optional, if not provided will try use what is in the pubkey file)") - 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") + addUserCmd.Flags().StringP("first-name", "F", "", "First name of the user") + addUserCmd.Flags().StringP("last-name", "L", "", "Last name of the user") + addUserCmd.Flags().StringP("email", "E", "", "Email address of the user") + addUserCmd.Flags().BoolP("reset-password", "", false, "Send a password reset email") + addUserSSHKeyCmd.Flags().StringP("email", "E", "", "Email address of the user") + addUserSSHKeyCmd.Flags().StringP("keyname", "N", "", "Name of the SSH key (optional, if not provided will try use what is in the pubkey file)") + addUserSSHKeyCmd.Flags().StringP("pubkey", "K", "", "Specify path to the public key to add") + addUserSSHKeyCmd.Flags().StringP("keyvalue", "V", "", "Value of the public key to add (ssh-ed25519 AAA..)") + deleteUserCmd.Flags().StringP("email", "E", "", "Email address of the user") 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") + updateUserCmd.Flags().StringP("first-name", "F", "", "New first name of the user") + updateUserCmd.Flags().StringP("last-name", "L", "", "New last name of the user") + updateUserCmd.Flags().StringP("email", "E", "", "New email address of the user") + updateUserCmd.Flags().StringP("current-email", "C", "", "Current email address of the user") 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)") addAdministratorToOrganizationCmd.Flags().StringP("organization-name", "O", "", "Name of the organization") @@ -562,5 +710,5 @@ func init() { removeAdministratorFromOrganizationCmd.Flags().StringP("organization-name", "O", "", "Name of the organization") removeAdministratorFromOrganizationCmd.Flags().StringP("email", "E", "", "Email address of the user") removeAdministratorFromOrganizationCmd.Flags().Bool("owner", false, "Set the user as an administrator of the organization") - resetPasswordCmd.Flags().StringVarP(&userEmail, "email", "E", "", "Email address of the user") + resetPasswordCmd.Flags().StringP("email", "E", "", "Email address of the user") } diff --git a/cmd/variables.go b/cmd/variables.go index 1924b6e9..88e6bc5a 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -3,13 +3,13 @@ package cmd import ( "context" "fmt" - "os" "strings" + "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + "github.com/uselagoon/machinery/api/schema" + "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" ) @@ -21,20 +21,14 @@ var addVariableCmd = &cobra.Command{ return validateTokenE(cmdLagoon) }, RunE: func(cmd *cobra.Command, args []string) error { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err } varName, err := cmd.Flags().GetString("name") if err != nil { return err } - if varName == "" { - fmt.Println("Missing arguments: variable name is not defined") - cmd.Help() - os.Exit(1) - } varValue, err := cmd.Flags().GetString("value") if err != nil { return err @@ -43,18 +37,19 @@ var addVariableCmd = &cobra.Command{ if err != nil { return err } - debug, err := cmd.Flags().GetBool("debug") - if err != nil { + if err := requiredInputCheck("Project name", cmdProjectName, "Variable name", varName); err != nil { return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) + in := &schema.EnvVariableByNameInput{ Project: cmdProjectName, Environment: cmdProjectEnvironment, @@ -110,30 +105,30 @@ var deleteVariableCmd = &cobra.Command{ return validateTokenE(cmdLagoon) }, RunE: func(cmd *cobra.Command, args []string) error { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err } varName, err := cmd.Flags().GetString("name") if err != nil { return err } - debug, err := cmd.Flags().GetBool("debug") - if err != nil { + if err := requiredInputCheck("Project name", cmdProjectName, "Variable name", varName); err != nil { return err } + deleteMsg := fmt.Sprintf("You are attempting to delete variable '%s' from project '%s', are you sure?", varName, cmdProjectName) if cmdProjectEnvironment != "" { deleteMsg = fmt.Sprintf("You are attempting to delete variable '%s' from environment '%s' in project '%s', are you sure?", varName, cmdProjectEnvironment, cmdProjectName) } if yesNo(deleteMsg) { current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) in := &schema.DeleteEnvVariableByNameInput{ Project: cmdProjectName, @@ -145,7 +140,7 @@ var deleteVariableCmd = &cobra.Command{ return err } resultData := output.Result{ - Result: string(deleteResult.DeleteEnvVar), + Result: deleteResult.DeleteEnvVar, } output.RenderResult(resultData, outputOptions) } diff --git a/cmd/whoami.go b/cmd/whoami.go index 8e3e1cbb..d8193548 100644 --- a/cmd/whoami.go +++ b/cmd/whoami.go @@ -5,9 +5,10 @@ import ( "fmt" "strings" + "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" "github.com/uselagoon/lagoon-cli/pkg/output" ) @@ -32,16 +33,17 @@ This is useful if you have multiple keys or accounts in multiple lagoons and nee } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) - user, err := lagoon.GetMeInfo(context.TODO(), lc) + user, err := lagoon.Me(context.TODO(), lc) if err != nil { - if strings.Contains(err.Error(), "Cannot read property 'access_token' of null") { + if strings.Contains(err.Error(), "Cannot read properties of null (reading 'access_token')") { return fmt.Errorf("unable to get user information, you may be using an administration token") } return err diff --git a/docs/commands/lagoon_add_project.md b/docs/commands/lagoon_add_project.md index 5011bf4a..72661d85 100644 --- a/docs/commands/lagoon_add_project.md +++ b/docs/commands/lagoon_add_project.md @@ -14,24 +14,25 @@ lagoon add project [flags] ### Options ``` - -a, --autoIdle uint Auto idle setting of the project - -b, --branches string Which branches should be deployed - -L, --developmentEnvironmentsLimit uint How many environments can be deployed at one time - -g, --gitUrl string GitURL of the project - -h, --help help for project - -j, --json string JSON string to patch - -S, --openshift uint Reference to OpenShift Object this Project should be deployed to - -o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated - --organization-id uint ID of the Organization to add the project to - -O, --organization-name string Name of the Organization to add the project to - --owner Add the user as an owner of the project - -I, --privateKey string Private key to use for the project - -E, --productionEnvironment string Which environment(the name) should be marked as the production environment - -m, --pullrequests string Which Pull Requests should be deployed - -Z, --routerPattern string Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com' - --standbyProductionEnvironment string Which environment(the name) should be marked as the standby production environment - -C, --storageCalc uint Should storage for this environment be calculated - -s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository + -a, --auto-idle uint Auto idle setting of the project + -b, --branches string Which branches should be deployed + --build-image string Build Image for the project + -L, --development-environments-limit uint How many environments can be deployed at one time + -g, --git-url string GitURL of the project + -h, --help help for project + -j, --json string JSON string to patch + -S, --openshift uint Reference to OpenShift Object this Project should be deployed to + -o, --openshift-project-pattern string Pattern of OpenShift Project/Namespace that should be generated + --organization-id uint ID of the Organization to add the project to + -O, --organization-name string Name of the Organization to add the project to + --owner Add the user as an owner of the project + -I, --private-key string Private key to use for the project + -E, --production-environment string Which environment(the name) should be marked as the production environment + -m, --pullrequests string Which Pull Requests should be deployed + -Z, --router-pattern string Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com' + --standby-production-environment string Which environment(the name) should be marked as the standby production environment + -C, --storage-calc uint Should storage for this environment be calculated + -s, --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 diff --git a/docs/commands/lagoon_add_user.md b/docs/commands/lagoon_add_user.md index b0a2e3c7..71fff3c9 100644 --- a/docs/commands/lagoon_add_user.md +++ b/docs/commands/lagoon_add_user.md @@ -9,11 +9,11 @@ lagoon add user [flags] ### Options ``` - -E, --email string Email address of the user - -F, --firstName string First name of the user - -h, --help help for user - -L, --lastName string Last name of the user - --reset-password Send a password reset email + -E, --email string Email address of the user + -F, --first-name string First name of the user + -h, --help help for user + -L, --last-name string Last name of the user + --reset-password Send a password reset email ``` ### Options inherited from parent commands diff --git a/docs/commands/lagoon_list_group-projects.md b/docs/commands/lagoon_list_group-projects.md index 125d020c..1b23f968 100644 --- a/docs/commands/lagoon_list_group-projects.md +++ b/docs/commands/lagoon_list_group-projects.md @@ -9,8 +9,9 @@ lagoon list group-projects [flags] ### Options ``` - -h, --help help for group-projects - -N, --name string Name of the group to list projects in + --all-projects All projects + -h, --help help for group-projects + -N, --name string Name of the group to list projects in ``` ### Options inherited from parent commands diff --git a/docs/commands/lagoon_run.md b/docs/commands/lagoon_run.md index 1b141fbf..34ae18a1 100644 --- a/docs/commands/lagoon_run.md +++ b/docs/commands/lagoon_run.md @@ -33,5 +33,5 @@ Run a task against an environment * [lagoon run drush-archivedump](lagoon_run_drush-archivedump.md) - Run a drush archive dump on an environment * [lagoon run drush-cacheclear](lagoon_run_drush-cacheclear.md) - Run a drush cache clear on an environment * [lagoon run drush-sqldump](lagoon_run_drush-sqldump.md) - Run a drush sql dump on an environment -* [lagoon run invoke](lagoon_run_invoke.md) - +* [lagoon run invoke](lagoon_run_invoke.md) - Invoke a task registered against an environment diff --git a/docs/commands/lagoon_run_invoke.md b/docs/commands/lagoon_run_invoke.md index c41ced3d..9f64ffb9 100644 --- a/docs/commands/lagoon_run_invoke.md +++ b/docs/commands/lagoon_run_invoke.md @@ -1,6 +1,6 @@ ## lagoon run invoke - +Invoke a task registered against an environment ### Synopsis diff --git a/docs/commands/lagoon_update_project.md b/docs/commands/lagoon_update_project.md index 09408989..60e940ad 100644 --- a/docs/commands/lagoon_update_project.md +++ b/docs/commands/lagoon_update_project.md @@ -9,25 +9,29 @@ lagoon update project [flags] ### Options ``` - -a, --autoIdle int Auto idle setting of the project - -b, --branches string Which branches should be deployed - --deploymentsDisabled int Admin only flag for disabling deployments on a project, 1 to disable deployments, 0 to enable - -L, --developmentEnvironmentsLimit int How many environments can be deployed at one time - --factsUi int Enables the Lagoon insights Facts tab in the UI. Set to 1 to enable, 0 to disable - -g, --gitUrl string GitURL of the project - -h, --help help for project - -j, --json string JSON string to patch - -N, --name string Change the name of the project by specifying a new name (careful!) - -S, --openshift int Reference to OpenShift Object this Project should be deployed to - -o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated - -I, --privateKey string Private key to use for the project - --problemsUi int Enables the Lagoon insights Problems tab in the UI. Set to 1 to enable, 0 to disable - -E, --productionEnvironment string Which environment(the name) should be marked as the production environment - -m, --pullrequests string Which Pull Requests should be deployed - -Z, --routerPattern string Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com' - --standbyProductionEnvironment string Which environment(the name) should be marked as the standby production environment - -C, --storageCalc int Should storage for this environment be calculated - -s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository + -a, --auto-idle uint Auto idle setting of the project + --availability string Availability of the project + -b, --branches string Which branches should be deployed + --build-image string Build Image for the project. Set to 'null' to remove the build image + --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 + -L, --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 + -g, --git-url string GitURL of the project + -h, --help help for project + -j, --json string JSON string to patch + -N, --name string Change the name of the project by specifying a new name (careful!) + -S, --openshift uint Reference to OpenShift Object this Project should be deployed to + -o, --openshift-project-pattern string Pattern of OpenShift Project/Namespace that should be generated + -I, --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 + -E, --production-environment string Which environment(the name) should be marked as the production environment + -m, --pullrequests string Which Pull Requests should be deployed + -Z, --router-pattern string Router pattern of the project, e.g. '${service}-${environment}-${project}.lagoon.example.com' + --standby-production-environment string Which environment(the name) should be marked as the standby production environment + -C, --storage-calc uint Should storage for this environment be calculated + -s, --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 diff --git a/docs/commands/lagoon_update_user.md b/docs/commands/lagoon_update_user.md index f4ed5db8..1f26313e 100644 --- a/docs/commands/lagoon_update_user.md +++ b/docs/commands/lagoon_update_user.md @@ -15,9 +15,9 @@ lagoon update user [flags] ``` -C, --current-email string Current email address of the user -E, --email string New email address of the user - -F, --firstName string New first name of the user + -F, --first-name string New first name of the user -h, --help help for user - -L, --lastName string New last name of the user + -L, --last-name string New last name of the user ``` ### Options inherited from parent commands diff --git a/go.mod b/go.mod index 19c26488..9f140ddd 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 - github.com/uselagoon/machinery v0.0.20 + github.com/uselagoon/machinery v0.0.22 golang.org/x/crypto v0.21.0 golang.org/x/term v0.18.0 gopkg.in/yaml.v3 v3.0.1 @@ -40,4 +40,4 @@ require ( golang.org/x/sys v0.18.0 // indirect ) -// replace github.com/uselagoon/machinery => ../machinery +//replace github.com/uselagoon/machinery => ../machinery diff --git a/go.sum b/go.sum index ab7a4eb7..87b0c805 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO 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/uselagoon/machinery v0.0.20 h1:4pGGX/Y5UwbT86TU9vaP7QyjGk8wvikUVDvkTpesvbs= -github.com/uselagoon/machinery v0.0.20/go.mod h1:NbgtEofjK2XY0iUpk9aMYazIo+W/NI56+UF72jv8zVY= +github.com/uselagoon/machinery v0.0.22 h1:4FVJRLS8he2NAZYMIJXQqVb25jQ03tF8dNhQbrBMX3g= +github.com/uselagoon/machinery v0.0.22/go.mod h1:NbgtEofjK2XY0iUpk9aMYazIo+W/NI56+UF72jv8zVY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/internal/lagoon/client/_lgraphql/addDeployTarget.graphql b/internal/lagoon/client/_lgraphql/addDeployTarget.graphql deleted file mode 100644 index e43e7193..00000000 --- a/internal/lagoon/client/_lgraphql/addDeployTarget.graphql +++ /dev/null @@ -1,40 +0,0 @@ -mutation ( - $name: String!, - $consoleUrl: String!, - $token: String, - $routerPattern: String, - $sshHost: String, - $sshPort: String, - $monitoringConfig: JSON, - $buildImage: String, - $friendlyName: String, - $cloudProvider: String, - $cloudRegion: String) { - addDeployTarget: addOpenshift(input: { - name: $name, - consoleUrl: $consoleUrl, - token: $token - routerPattern: $routerPattern, - sshHost: $sshHost, - sshPort: $sshPort, - buildImage: $buildImage, - monitoringConfig: $monitoringConfig, - friendlyName: $friendlyName, - cloudProvider: $cloudProvider, - cloudRegion: $cloudRegion - }) { - id - name - created - token - consoleUrl - sshHost - sshPort - cloudProvider - cloudRegion - friendlyName - buildImage - routerPattern - monitoringConfig - } - } diff --git a/internal/lagoon/client/_lgraphql/addRestore.graphql b/internal/lagoon/client/_lgraphql/addRestore.graphql deleted file mode 100644 index 7e3c1eb8..00000000 --- a/internal/lagoon/client/_lgraphql/addRestore.graphql +++ /dev/null @@ -1,6 +0,0 @@ -mutation ( - $backupid: String!) { - addRestore(input: {backupId: $backupid}) { - id - } - } diff --git a/internal/lagoon/client/_lgraphql/backupsForEnvironmentByName.graphql b/internal/lagoon/client/_lgraphql/backupsForEnvironmentByName.graphql deleted file mode 100644 index dedaf552..00000000 --- a/internal/lagoon/client/_lgraphql/backupsForEnvironmentByName.graphql +++ /dev/null @@ -1,25 +0,0 @@ -query ( - $name: String!, - $project: Int!) { - environmentByName( - name: $name, - project: $project) - { - id - name - backups{ - id - source - backupId - created - deleted - restore{ - id - status - created - backupId - restoreLocation - } - } - } - } diff --git a/internal/lagoon/client/_lgraphql/deleteDeployTarget.graphql b/internal/lagoon/client/_lgraphql/deleteDeployTarget.graphql deleted file mode 100644 index 319ddbbf..00000000 --- a/internal/lagoon/client/_lgraphql/deleteDeployTarget.graphql +++ /dev/null @@ -1,7 +0,0 @@ -mutation ( - $name: String! -) { - deleteDeployTarget: deleteOpenshift(input: { - name: $name - }) -} diff --git a/internal/lagoon/client/_lgraphql/deleteDeployTargetConfig.graphql b/internal/lagoon/client/_lgraphql/deleteDeployTargetConfig.graphql deleted file mode 100644 index 35c27761..00000000 --- a/internal/lagoon/client/_lgraphql/deleteDeployTargetConfig.graphql +++ /dev/null @@ -1,9 +0,0 @@ -mutation ( - $id: Int! - $project: Int! -){ - deleteDeployTargetConfig(input:{ - id: $id - project: $project - }) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/deployEnvironmentBranch.graphql b/internal/lagoon/client/_lgraphql/deployEnvironmentBranch.graphql deleted file mode 100644 index c525929b..00000000 --- a/internal/lagoon/client/_lgraphql/deployEnvironmentBranch.graphql +++ /dev/null @@ -1,17 +0,0 @@ -mutation ( - $project: String!, - $branch: String!, - $branchRef: String, - $returnData: Boolean!, - $buildVariables: [EnvKeyValueInput]) { - deployEnvironmentBranch(input: { - project:{ - name: $project - } - branchName: $branch - branchRef: $branchRef - returnData: $returnData - buildVariables: $buildVariables - } - ) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/deployEnvironmentLatest.graphql b/internal/lagoon/client/_lgraphql/deployEnvironmentLatest.graphql deleted file mode 100644 index 9cb12a53..00000000 --- a/internal/lagoon/client/_lgraphql/deployEnvironmentLatest.graphql +++ /dev/null @@ -1,9 +0,0 @@ -mutation ( - $environment: EnvironmentInput!, $returnData: Boolean!, $buildVariables: [EnvKeyValueInput]) { - deployEnvironmentLatest(input: { - environment: $environment - returnData: $returnData - buildVariables: $buildVariables - } - ) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/deployEnvironmentPromote.graphql b/internal/lagoon/client/_lgraphql/deployEnvironmentPromote.graphql deleted file mode 100644 index 6dea598a..00000000 --- a/internal/lagoon/client/_lgraphql/deployEnvironmentPromote.graphql +++ /dev/null @@ -1,22 +0,0 @@ -mutation ( - $project: String!, - $sourceEnvironment: String!, - $destinationEnvironment: String!, - $returnData: Boolean!, - $buildVariables: [EnvKeyValueInput]) { - deployEnvironmentPromote(input:{ - sourceEnvironment:{ - name: $sourceEnvironment - project:{ - name: $project - } - } - project:{ - name: $project - } - destinationEnvironment: $destinationEnvironment - buildVariables: $buildVariables - returnData: $returnData - } - ) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/deployEnvironmentPullrequest.graphql b/internal/lagoon/client/_lgraphql/deployEnvironmentPullrequest.graphql deleted file mode 100644 index 1dba7404..00000000 --- a/internal/lagoon/client/_lgraphql/deployEnvironmentPullrequest.graphql +++ /dev/null @@ -1,23 +0,0 @@ -mutation ( - $project: ProjectInput!, - $number: Int!, - $title: String!, - $baseBranchName: String!, - $baseBranchRef: String!, - $headBranchName: String!, - $headBranchRef: String!, - $returnData: Boolean!, - $buildVariables: [EnvKeyValueInput]) { - deployEnvironmentPullrequest(input: { - project: $project - number: $number - title: $title - baseBranchName: $baseBranchName - baseBranchRef: $baseBranchRef - headBranchName: $headBranchName - headBranchRef: $headBranchRef - returnData: $returnData - buildVariables: $buildVariables - } - ) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/deployTargetConfigsByProjectId.graphql b/internal/lagoon/client/_lgraphql/deployTargetConfigsByProjectId.graphql deleted file mode 100644 index 3f51fe2e..00000000 --- a/internal/lagoon/client/_lgraphql/deployTargetConfigsByProjectId.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query ( - $project: Int! -){ - deployTargetConfigsByProjectId( - project: $project - ){ - id - deployTarget{ - id - name - friendlyName - cloudProvider - cloudRegion - } - branches - pullrequests - weight - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/listDeployTargets.graphql b/internal/lagoon/client/_lgraphql/listDeployTargets.graphql deleted file mode 100644 index 2da31a19..00000000 --- a/internal/lagoon/client/_lgraphql/listDeployTargets.graphql +++ /dev/null @@ -1,17 +0,0 @@ -query { - listDeployTargets: allKubernetes{ - id - name - created - consoleUrl - cloudRegion - cloudProvider - friendlyName - token - sshHost - sshPort - buildImage - routerPattern - monitoringConfig - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/me.graphql b/internal/lagoon/client/_lgraphql/me.graphql deleted file mode 100644 index 43f60d2b..00000000 --- a/internal/lagoon/client/_lgraphql/me.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query { - me { - id - email - firstName - lastName - sshKeys { - id - name - keyType - keyValue - keyFingerprint - created - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/minimalProjectByName.graphql b/internal/lagoon/client/_lgraphql/minimalProjectByName.graphql deleted file mode 100644 index 71c2e83d..00000000 --- a/internal/lagoon/client/_lgraphql/minimalProjectByName.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query ( - $name: String!) { - projectByName( - name: $name) { - id - name - autoIdle - branches - pullrequests - productionEnvironment - openshiftProjectPattern - developmentEnvironmentsLimit - gitUrl - autoIdle - openshift{ - id - } - } - } diff --git a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationEmail.graphql b/internal/lagoon/client/_lgraphql/notifications/deleteNotificationEmail.graphql deleted file mode 100644 index df172dd0..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationEmail.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation ($name: String!) { - deleteNotification: deleteNotificationEmail(input:{name: $name}) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationMicrosoftTeams.graphql b/internal/lagoon/client/_lgraphql/notifications/deleteNotificationMicrosoftTeams.graphql deleted file mode 100644 index 2b28338f..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationMicrosoftTeams.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation ($name: String!) { - deleteNotification: deleteNotificationMicrosoftTeams(input:{name: $name}) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationRocketChat.graphql b/internal/lagoon/client/_lgraphql/notifications/deleteNotificationRocketChat.graphql deleted file mode 100644 index 6f320787..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationRocketChat.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation ($name: String!) { - deleteNotification: deleteNotificationRocketChat(input:{name: $name}) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationSlack.graphql b/internal/lagoon/client/_lgraphql/notifications/deleteNotificationSlack.graphql deleted file mode 100644 index 0b298edd..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationSlack.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation ($name: String!) { - deleteNotification: deleteNotificationSlack(input:{name: $name}) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationWebhook.graphql b/internal/lagoon/client/_lgraphql/notifications/deleteNotificationWebhook.graphql deleted file mode 100644 index 2e58d2f0..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/deleteNotificationWebhook.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation ($name: String!) { - deleteNotification: deleteNotificationWebhook(input:{name: $name}) -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationEmail.graphql b/internal/lagoon/client/_lgraphql/notifications/listAllNotificationEmail.graphql deleted file mode 100644 index 4e13e955..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationEmail.graphql +++ /dev/null @@ -1,13 +0,0 @@ -query { - allProjects { - name - id - notifications(type: EMAIL) { - ... on NotificationEmail { - __typename - emailAddress - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationMicrosoftTeams.graphql b/internal/lagoon/client/_lgraphql/notifications/listAllNotificationMicrosoftTeams.graphql deleted file mode 100644 index 4691db9a..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationMicrosoftTeams.graphql +++ /dev/null @@ -1,13 +0,0 @@ -query { - allProjects { - name - id - notifications(type: MICROSOFTTEAMS) { - ... on NotificationMicrosoftTeams { - __typename - webhook - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationRocketChat.graphql b/internal/lagoon/client/_lgraphql/notifications/listAllNotificationRocketChat.graphql deleted file mode 100644 index 2e63e6db..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationRocketChat.graphql +++ /dev/null @@ -1,14 +0,0 @@ -query { - allProjects { - name - id - notifications(type: ROCKETCHAT) { - ... on NotificationRocketChat { - __typename - webhook - channel - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationSlack.graphql b/internal/lagoon/client/_lgraphql/notifications/listAllNotificationSlack.graphql deleted file mode 100644 index 05188bda..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationSlack.graphql +++ /dev/null @@ -1,14 +0,0 @@ -query { - allProjects { - name - id - notifications(type: SLACK) { - ... on NotificationSlack { - __typename - webhook - channel - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationWebhook.graphql b/internal/lagoon/client/_lgraphql/notifications/listAllNotificationWebhook.graphql deleted file mode 100644 index 6e25d996..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/listAllNotificationWebhook.graphql +++ /dev/null @@ -1,13 +0,0 @@ -query { - allProjects { - name - id - notifications(type: WEBHOOK) { - ... on NotificationWebhook { - __typename - webhook - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/projectNotificationEmail.graphql b/internal/lagoon/client/_lgraphql/notifications/projectNotificationEmail.graphql deleted file mode 100644 index f973d201..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/projectNotificationEmail.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - notifications(type: EMAIL) { - ... on NotificationEmail { - __typename - emailAddress - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/projectNotificationMicrosoftTeams.graphql b/internal/lagoon/client/_lgraphql/notifications/projectNotificationMicrosoftTeams.graphql deleted file mode 100644 index 2fe84f4e..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/projectNotificationMicrosoftTeams.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - notifications(type: MICROSOFTTEAMS) { - ... on NotificationMicrosoftTeams { - __typename - webhook - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/projectNotificationRocketChat.graphql b/internal/lagoon/client/_lgraphql/notifications/projectNotificationRocketChat.graphql deleted file mode 100644 index 555fdc51..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/projectNotificationRocketChat.graphql +++ /dev/null @@ -1,12 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - notifications(type: ROCKETCHAT) { - ... on NotificationRocketChat { - __typename - webhook - channel - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/projectNotificationSlack.graphql b/internal/lagoon/client/_lgraphql/notifications/projectNotificationSlack.graphql deleted file mode 100644 index cd525e14..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/projectNotificationSlack.graphql +++ /dev/null @@ -1,12 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - notifications(type: SLACK) { - ... on NotificationSlack { - __typename - webhook - channel - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/projectNotificationWebhook.graphql b/internal/lagoon/client/_lgraphql/notifications/projectNotificationWebhook.graphql deleted file mode 100644 index a1ffd5ec..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/projectNotificationWebhook.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - notifications(type: WEBHOOK) { - ... on NotificationWebhook { - __typename - webhook - name - } - } - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/removeNotificationFromProject.graphql b/internal/lagoon/client/_lgraphql/notifications/removeNotificationFromProject.graphql deleted file mode 100644 index 8073fc66..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/removeNotificationFromProject.graphql +++ /dev/null @@ -1,15 +0,0 @@ -mutation ( - $project: String! - $notificationType: NotificationType! - $notificationName: String! -){ - removeNotificationFromProject( - input:{ - project: $project - notificationType: $notificationType - notificationName: $notificationName - } - ){ - id - } -} diff --git a/internal/lagoon/client/_lgraphql/notifications/updateNotificationEmail.graphql b/internal/lagoon/client/_lgraphql/notifications/updateNotificationEmail.graphql deleted file mode 100644 index 3f99f72e..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/updateNotificationEmail.graphql +++ /dev/null @@ -1,15 +0,0 @@ -mutation ( - $name: String! - $patch: UpdateNotificationEmailPatchInput! -) { - updateNotificationEmail( - input:{ - name: $name - patch: $patch - } - ){ - id - name - emailAddress - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/updateNotificationMicrosoftTeams.graphql b/internal/lagoon/client/_lgraphql/notifications/updateNotificationMicrosoftTeams.graphql deleted file mode 100644 index c5799811..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/updateNotificationMicrosoftTeams.graphql +++ /dev/null @@ -1,15 +0,0 @@ -mutation ( - $name: String! - $patch: UpdateNotificationMicrosoftTeamsPatchInput! -) { - updateNotificationMicrosoftTeams( - input:{ - name: $name - patch: $patch - } - ){ - id - name - webhook - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/updateNotificationRocketChat.graphql b/internal/lagoon/client/_lgraphql/notifications/updateNotificationRocketChat.graphql deleted file mode 100644 index 74260f23..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/updateNotificationRocketChat.graphql +++ /dev/null @@ -1,16 +0,0 @@ -mutation ( - $name: String! - $patch: UpdateNotificationRocketChatPatchInput! -) { - updateNotificationRocketChat( - input:{ - name: $name - patch: $patch - } - ){ - id - name - channel - webhook - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/updateNotificationSlack.graphql b/internal/lagoon/client/_lgraphql/notifications/updateNotificationSlack.graphql deleted file mode 100644 index 8e38f3c8..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/updateNotificationSlack.graphql +++ /dev/null @@ -1,16 +0,0 @@ -mutation ( - $name: String! - $patch: UpdateNotificationSlackPatchInput! -) { - updateNotificationSlack( - input:{ - name: $name - patch: $patch - } - ){ - id - name - channel - webhook - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/notifications/updateNotificationWebhook.graphql b/internal/lagoon/client/_lgraphql/notifications/updateNotificationWebhook.graphql deleted file mode 100644 index b94d2ac7..00000000 --- a/internal/lagoon/client/_lgraphql/notifications/updateNotificationWebhook.graphql +++ /dev/null @@ -1,15 +0,0 @@ -mutation ( - $name: String! - $patch: UpdateNotificationWebhookPatchInput! -) { - updateNotificationWebhook( - input:{ - name: $name - patch: $patch - } - ){ - id - name - webhook - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/projectByNameMetadata.graphql b/internal/lagoon/client/_lgraphql/projectByNameMetadata.graphql deleted file mode 100644 index fe9a8536..00000000 --- a/internal/lagoon/client/_lgraphql/projectByNameMetadata.graphql +++ /dev/null @@ -1,9 +0,0 @@ -query ( - $name: String!) { - projectByName( - name: $name) { - id - name - metadata - } - } diff --git a/internal/lagoon/client/_lgraphql/sshEndpointsByProject.graphql b/internal/lagoon/client/_lgraphql/sshEndpointsByProject.graphql deleted file mode 100644 index 13517b58..00000000 --- a/internal/lagoon/client/_lgraphql/sshEndpointsByProject.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query ($name: String!) { - projectByName(name: $name) { - id - name - environments { - id - name - openshiftProjectName - openshift{ - id - sshHost - sshPort - } - } - } -} diff --git a/internal/lagoon/client/_lgraphql/updateDeployTarget.graphql b/internal/lagoon/client/_lgraphql/updateDeployTarget.graphql deleted file mode 100644 index ec62a81e..00000000 --- a/internal/lagoon/client/_lgraphql/updateDeployTarget.graphql +++ /dev/null @@ -1,44 +0,0 @@ -mutation ( - $id: Int! - $name: String, - $consoleUrl: String, - $token: String, - $routerPattern: String, - $sshHost: String, - $sshPort: String, - $monitoringConfig: JSON, - $buildImage: String, - $friendlyName: String, - $cloudProvider: String, - $cloudRegion: String) { - updateDeployTarget: updateOpenshift(input: { - id: $id - patch: { - name: $name, - consoleUrl: $consoleUrl, - token: $token - routerPattern: $routerPattern, - sshHost: $sshHost, - sshPort: $sshPort, - buildImage: $buildImage, - monitoringConfig: $monitoringConfig, - friendlyName: $friendlyName, - cloudProvider: $cloudProvider, - cloudRegion: $cloudRegion - } - }) { - id - name - created - token - consoleUrl - sshHost - sshPort - buildImage - cloudProvider - cloudRegion - friendlyName - routerPattern - monitoringConfig - } - } diff --git a/internal/lagoon/client/_lgraphql/updateDeployTargetConfig.graphql b/internal/lagoon/client/_lgraphql/updateDeployTargetConfig.graphql deleted file mode 100644 index e39f82b3..00000000 --- a/internal/lagoon/client/_lgraphql/updateDeployTargetConfig.graphql +++ /dev/null @@ -1,31 +0,0 @@ -mutation ( - $id: Int! - $weight: Int - $branches: String - $pullrequests: String - $deployTarget: Int - $deployTargetProjectPattern: String -){ - updateDeployTargetConfig(input:{ - id: $id - patch:{ - deployTarget: $deployTarget - weight: $weight - branches: $branches - pullrequests: $pullrequests - deployTargetProjectPattern: $deployTargetProjectPattern - } - }){ - id - deployTarget{ - id - name - friendlyName - cloudProvider - cloudRegion - } - branches - pullrequests - weight - } -} \ No newline at end of file diff --git a/internal/lagoon/client/_lgraphql/variables/addOrUpdateEnvVariableByName.graphql b/internal/lagoon/client/_lgraphql/variables/addOrUpdateEnvVariableByName.graphql deleted file mode 100644 index 83d5e5f5..00000000 --- a/internal/lagoon/client/_lgraphql/variables/addOrUpdateEnvVariableByName.graphql +++ /dev/null @@ -1,10 +0,0 @@ -mutation ( - $input: EnvVariableByNameInput! -) { - addOrUpdateEnvVariableByName(input: $input) { - id - name - value - scope - } -} diff --git a/internal/lagoon/client/_lgraphql/variables/deleteEnvVariableByName.graphql b/internal/lagoon/client/_lgraphql/variables/deleteEnvVariableByName.graphql deleted file mode 100644 index e1a87d41..00000000 --- a/internal/lagoon/client/_lgraphql/variables/deleteEnvVariableByName.graphql +++ /dev/null @@ -1,5 +0,0 @@ -mutation ( - $input: DeleteEnvVariableByNameInput! -) { - deleteEnvVariableByName(input: $input) -} diff --git a/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql b/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql deleted file mode 100644 index f24d0450..00000000 --- a/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql +++ /dev/null @@ -1,10 +0,0 @@ -query ( - $input: EnvVariableByProjectEnvironmentNameInput! -){ - getEnvVariablesByProjectEnvironmentName(input: $input) { - id - name - value - scope - } -} diff --git a/internal/lagoon/client/mutation.go b/internal/lagoon/client/mutation.go index a4917238..d3a7f5ef 100644 --- a/internal/lagoon/client/mutation.go +++ b/internal/lagoon/client/mutation.go @@ -20,42 +20,6 @@ func wrapErr(err error) error { return err } -// AddDeployTarget adds a deploytarget (kubernetes/openshift). -func (c *Client) AddDeployTarget(ctx context.Context, in *schema.AddDeployTargetInput, out *schema.AddDeployTargetResponse) error { - req, err := c.newRequest("_lgraphql/addDeployTarget.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.AddDeployTargetResponse `json:"addDeployTarget"` - }{ - Response: out, - }) -} - -// UpdateDeployTarget updates a deploytarget (kubernetes/openshift). -func (c *Client) UpdateDeployTarget(ctx context.Context, in *schema.UpdateDeployTargetInput, out *schema.UpdateDeployTargetResponse) error { - req, err := c.newRequest("_lgraphql/updateDeployTarget.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.UpdateDeployTargetResponse `json:"updateDeployTarget"` - }{ - Response: out, - }) -} - -// DeleteDeployTarget deletes a deploytarget (kubernetes/openshift). -func (c *Client) DeleteDeployTarget(ctx context.Context, in *schema.DeleteDeployTargetInput, out *schema.DeleteDeployTargetResponse) error { - req, err := c.newRequest("_lgraphql/deleteDeployTarget.graphql", in) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &out) -} - // AddGroup adds a group. func (c *Client) AddGroup( ctx context.Context, in *schema.AddGroupInput, out *schema.Group) error { @@ -167,117 +131,3 @@ func (c *Client) AddGroupsToProject(ctx context.Context, Response: out, }) } - -// DeployEnvironmentLatest deploys a latest environment. -func (c *Client) DeployEnvironmentLatest(ctx context.Context, - in *schema.DeployEnvironmentLatestInput, out *schema.DeployEnvironmentLatest) error { - req, err := c.newRequest("_lgraphql/deployEnvironmentLatest.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeployEnvironmentPullrequest deploys a pullreguest. -func (c *Client) DeployEnvironmentPullrequest(ctx context.Context, - in *schema.DeployEnvironmentPullrequestInput, out *schema.DeployEnvironmentPullrequest) error { - req, err := c.newRequest("_lgraphql/deployEnvironmentPullrequest.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeployEnvironmentPromote promotes one environment into a new environment. -func (c *Client) DeployEnvironmentPromote(ctx context.Context, - in *schema.DeployEnvironmentPromoteInput, out *schema.DeployEnvironmentPromote) error { - req, err := c.newRequest("_lgraphql/deployEnvironmentPromote.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeployEnvironmentBranch deploys a branch. -func (c *Client) DeployEnvironmentBranch(ctx context.Context, - in *schema.DeployEnvironmentBranchInput, out *schema.DeployEnvironmentBranch) error { - req, err := c.newRequest("_lgraphql/deployEnvironmentBranch.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// AddRestore adds a restore. -func (c *Client) AddRestore( - ctx context.Context, backupID string, out *schema.Restore) error { - req, err := c.newRequest("_lgraphql/addRestore.graphql", - map[string]interface{}{ - "backupid": backupID, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.Restore `json:"addRestore"` - }{ - Response: out, - }) -} - -// UpdateDeployTargetConfiguration adds a deploytarget configuration to a project. -func (c *Client) UpdateDeployTargetConfiguration(ctx context.Context, - in *schema.UpdateDeployTargetConfigInput, out *schema.DeployTargetConfig) error { - req, err := c.newRequest("_lgraphql/updateDeployTargetConfig.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.DeployTargetConfig `json:"updateDeployTargetConfig"` - }{ - Response: out, - }) -} - -// DeleteDeployTargetConfig deletes a deploytarget config from a project. -func (c *Client) DeleteDeployTargetConfiguration(ctx context.Context, - id int, project int, out *schema.DeleteDeployTargetConfig) error { - req, err := c.newRequest("_lgraphql/deleteDeployTargetConfig.graphql", - map[string]interface{}{ - "id": id, - "project": project, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// AddOrUpdateEnvVariableByName adds or updates an environment variable in the api -func (c *Client) AddOrUpdateEnvVariableByName(ctx context.Context, in *schema.EnvVariableByNameInput, out *schema.UpdateEnvVarResponse) error { - req, err := c.newRequest("_lgraphql/variables/addOrUpdateEnvVariableByName.graphql", - map[string]interface{}{ - "input": in, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.UpdateEnvVarResponse `json:"addOrUpdateEnvVariableByName"` - }{ - Response: out, - }) -} - -// DeleteEnvVariableByName deletes an environment variable from the api -func (c *Client) DeleteEnvVariableByName(ctx context.Context, in *schema.DeleteEnvVariableByNameInput, out *schema.DeleteEnvVarResponse) error { - req, err := c.newRequest("_lgraphql/variables/deleteEnvVariableByName.graphql", - map[string]interface{}{ - "input": in, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &out) -} diff --git a/internal/lagoon/client/notification.go b/internal/lagoon/client/notification.go index 51510632..aece9756 100644 --- a/internal/lagoon/client/notification.go +++ b/internal/lagoon/client/notification.go @@ -80,171 +80,6 @@ func (c *Client) AddNotificationWebhook(ctx context.Context, }) } -// UpdateNotificationEmail updates an email notification. -func (c *Client) UpdateNotificationEmail( - ctx context.Context, input *schema.UpdateNotificationEmailInput, out *schema.NotificationEmail) error { - - req, err := c.newVersionedRequest("_lgraphql/notifications/updateNotificationEmail.graphql", - map[string]interface{}{ - "name": input.Name, - "patch": input.Patch, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.NotificationEmail `json:"updateNotificationEmail"` - }{ - Response: out, - }) -} - -// UpdateNotificationSlack updates a slack notification. -func (c *Client) UpdateNotificationSlack( - ctx context.Context, input *schema.UpdateNotificationSlackInput, out *schema.NotificationSlack) error { - - req, err := c.newVersionedRequest("_lgraphql/notifications/updateNotificationSlack.graphql", - map[string]interface{}{ - "name": input.Name, - "patch": input.Patch, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.NotificationSlack `json:"updateNotificationSlack"` - }{ - Response: out, - }) -} - -// UpdateNotificationRocketChat updates a rocket chat notification. -func (c *Client) UpdateNotificationRocketChat( - ctx context.Context, input *schema.UpdateNotificationRocketChatInput, out *schema.NotificationRocketChat) error { - - req, err := c.newVersionedRequest("_lgraphql/notifications/updateNotificationRocketChat.graphql", - map[string]interface{}{ - "name": input.Name, - "patch": input.Patch, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.NotificationRocketChat `json:"updateNotificationRocketChat"` - }{ - Response: out, - }) -} - -// UpdateNotificationMicrosoftTeams updates a microsoft teams notification. -func (c *Client) UpdateNotificationMicrosoftTeams( - ctx context.Context, input *schema.UpdateNotificationMicrosoftTeamsInput, out *schema.NotificationMicrosoftTeams) error { - - req, err := c.newVersionedRequest("_lgraphql/notifications/updateNotificationMicrosoftTeams.graphql", - map[string]interface{}{ - "name": input.Name, - "patch": input.Patch, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.NotificationMicrosoftTeams `json:"updateNotificationMicrosoftTeams"` - }{ - Response: out, - }) -} - -// UpdateNotificationWebhook updates a webhook notification. -func (c *Client) UpdateNotificationWebhook( - ctx context.Context, input *schema.UpdateNotificationWebhookInput, out *schema.NotificationWebhook) error { - - req, err := c.newVersionedRequest("_lgraphql/notifications/updateNotificationWebhook.graphql", - map[string]interface{}{ - "name": input.Name, - "patch": input.Patch, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.NotificationWebhook `json:"updateNotificationWebhook"` - }{ - Response: out, - }) -} - -// DeleteNotificationSlack deletes a Slack notification. -func (c *Client) DeleteNotificationSlack(ctx context.Context, - name string, - out *schema.DeleteNotification) error { - req, err := c.newRequest("_lgraphql/notifications/deleteNotificationSlack.graphql", map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeleteNotificationRocketChat deletes a RocketChat notification. -func (c *Client) DeleteNotificationRocketChat(ctx context.Context, - name string, - out *schema.DeleteNotification) error { - req, err := c.newRequest("_lgraphql/notifications/deleteNotificationRocketChat.graphql", map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeleteNotificationEmail deletes an Email notification. -func (c *Client) DeleteNotificationEmail(ctx context.Context, - name string, - out *schema.DeleteNotification) error { - req, err := c.newRequest("_lgraphql/notifications/deleteNotificationEmail.graphql", map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeleteNotificationMicrosoftTeams deletes a MicrosoftTeams notification. -func (c *Client) DeleteNotificationMicrosoftTeams(ctx context.Context, - name string, - out *schema.DeleteNotification) error { - req, err := c.newRequest("_lgraphql/notifications/deleteNotificationMicrosoftTeams.graphql", map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - -// DeleteNotificationWebhook deletes a Webhook notification. -func (c *Client) DeleteNotificationWebhook(ctx context.Context, - name string, - out *schema.DeleteNotification) error { - req, err := c.newRequest("_lgraphql/notifications/deleteNotificationWebhook.graphql", map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - return c.client.Run(ctx, req, &out) -} - // AddNotificationToProject adds a Notification to a Project. func (c *Client) AddNotificationToProject(ctx context.Context, in *schema.AddNotificationToProjectInput, out *schema.Project) error { @@ -258,192 +93,3 @@ func (c *Client) AddNotificationToProject(ctx context.Context, Response: out, }) } - -// RemoveNotificationFromProject removes a Notification from a Project. -func (c *Client) RemoveNotificationFromProject(ctx context.Context, - in *schema.RemoveNotificationFromProjectInput, out *schema.Project) error { - req, err := c.newRequest("_lgraphql/notifications/removeNotificationFromProject.graphql", in) - if err != nil { - return err - } - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"removeNotificationFromProject"` - }{ - Response: out, - }) -} - -// GetProjectNotificationEmail queries the Lagoon API for notifications of the requested type -func (c *Client) GetProjectNotificationEmail( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/projectNotificationEmail.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// GetAllNotificationEmail queries the Lagoon API for notifications of the requested type -func (c *Client) GetAllNotificationEmail( - ctx context.Context, projects *[]schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/listAllNotificationEmail.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.Project `json:"allProjects"` - }{ - Response: projects, - }) -} - -// GetProjectNotificationWebhook queries the Lagoon API for notifications of the requested type -func (c *Client) GetProjectNotificationWebhook( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/projectNotificationWebhook.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// GetAllNotificationWebhook queries the Lagoon API for notifications of the requested type -func (c *Client) GetAllNotificationWebhook( - ctx context.Context, projects *[]schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/listAllNotificationWebhook.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.Project `json:"allProjects"` - }{ - Response: projects, - }) -} - -// GetProjectNotificationSlack queries the Lagoon API for notifications of the requested type -func (c *Client) GetProjectNotificationSlack( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/projectNotificationSlack.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// GetAllNotificationSlack queries the Lagoon API for notifications of the requested type -func (c *Client) GetAllNotificationSlack( - ctx context.Context, projects *[]schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/listAllNotificationSlack.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.Project `json:"allProjects"` - }{ - Response: projects, - }) -} - -// GetProjectNotificationRocketChat queries the Lagoon API for notifications of the requested type -func (c *Client) GetProjectNotificationRocketChat( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/projectNotificationRocketChat.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// GetAllNotificationRocketChat queries the Lagoon API for notifications of the requested type -func (c *Client) GetAllNotificationRocketChat( - ctx context.Context, projects *[]schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/listAllNotificationRocketChat.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.Project `json:"allProjects"` - }{ - Response: projects, - }) -} - -// GetProjectNotificationMicrosoftTeams queries the Lagoon API for notifications of the requested type -func (c *Client) GetProjectNotificationMicrosoftTeams( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/projectNotificationMicrosoftTeams.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// GetAllNotificationMicrosoftTeams queries the Lagoon API for notifications of the requested type -func (c *Client) GetAllNotificationMicrosoftTeams( - ctx context.Context, projects *[]schema.Project) error { - - req, err := c.newRequest("_lgraphql/notifications/listAllNotificationMicrosoftTeams.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.Project `json:"allProjects"` - }{ - Response: projects, - }) -} diff --git a/internal/lagoon/client/query.go b/internal/lagoon/client/query.go index 2957d21c..aefe1fff 100644 --- a/internal/lagoon/client/query.go +++ b/internal/lagoon/client/query.go @@ -26,24 +26,6 @@ func (c *Client) ProjectByName( }) } -// Me queries the Lagoon API for me, and -// unmarshals the response into project. -func (c *Client) Me( - ctx context.Context, user *schema.User) error { - - req, err := c.newRequest("_lgraphql/me.graphql", - nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.User `json:"me"` - }{ - Response: user, - }) -} - // EnvironmentByName queries the Lagoon API for an environment by its name and // parent projectID, and unmarshals the response into environment. func (c *Client) EnvironmentByName(ctx context.Context, name string, @@ -65,27 +47,6 @@ func (c *Client) EnvironmentByName(ctx context.Context, name string, }) } -// BackupsForEnvironmentByName queries the Lagoon API for an environment by its name and -// parent projectID, and unmarshals the response into environment. -func (c *Client) BackupsForEnvironmentByName(ctx context.Context, name string, - projectID uint, environment *schema.Environment) error { - - req, err := c.newRequest("_lgraphql/backupsForEnvironmentByName.graphql", - map[string]interface{}{ - "name": name, - "project": projectID, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Environment `json:"environmentByName"` - }{ - Response: environment, - }) -} - // LagoonAPIVersion queries the Lagoon API for its version, and // unmarshals the response. func (c *Client) LagoonAPIVersion( @@ -117,118 +78,3 @@ func (c *Client) LagoonSchema( Response: lagoonSchema, }) } - -// MinimalProjectByName queries the Lagoon API for a project by its name, and -// unmarshals the response into project. -func (c *Client) MinimalProjectByName( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newVersionedRequest("_lgraphql/minimalProjectByName.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// ProjectByNameMetadata queries the Lagoon API for a project by its name, and -// unmarshals the response into project. -func (c *Client) ProjectByNameMetadata( - ctx context.Context, name string, project *schema.ProjectMetadata) error { - - req, err := c.newVersionedRequest("_lgraphql/projectByNameMetadata.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.ProjectMetadata `json:"projectByName"` - }{ - Response: project, - }) -} - -// DeployTargetConfigsByProjectID queries the Lagoon API for a projects deploytarget configs by its id, and -// unmarshals the response into deploytargetconfigs. -func (c *Client) DeployTargetConfigsByProjectID( - ctx context.Context, project int, deploytargetconfigs *[]schema.DeployTargetConfig) error { - - req, err := c.newVersionedRequest("_lgraphql/deployTargetConfigsByProjectId.graphql", - map[string]interface{}{ - "project": project, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.DeployTargetConfig `json:"deployTargetConfigsByProjectId"` - }{ - Response: deploytargetconfigs, - }) -} - -// SSHEndpointsByProject queries the Lagoon API for a project by its name, and -// unmarshals the response into project. -func (c *Client) SSHEndpointsByProject( - ctx context.Context, name string, project *schema.Project) error { - - req, err := c.newVersionedRequest("_lgraphql/sshEndpointsByProject.graphql", - map[string]interface{}{ - "name": name, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *schema.Project `json:"projectByName"` - }{ - Response: project, - }) -} - -// ListDeployTargets queries the Lagoon API for a deploytargets and unmarshals the response into deploytargets. -func (c *Client) ListDeployTargets( - ctx context.Context, deploytargets *[]schema.DeployTarget) error { - - req, err := c.newRequest("_lgraphql/listDeployTargets.graphql", nil) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.DeployTarget `json:"listDeployTargets"` - }{ - Response: deploytargets, - }) -} - -// GetEnvVariablesByProjectEnvironmentName queries the Lagoon API for a envvars by project environment and unmarshals the response. -func (c *Client) GetEnvVariablesByProjectEnvironmentName( - ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, envkeyvalue *[]schema.EnvKeyValue) error { - - req, err := c.newRequest("_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql", - map[string]interface{}{ - "input": in, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.EnvKeyValue `json:"getEnvVariablesByProjectEnvironmentName"` - }{ - Response: envkeyvalue, - }) -} diff --git a/internal/lagoon/deploy.go b/internal/lagoon/deploy.go deleted file mode 100644 index b0203520..00000000 --- a/internal/lagoon/deploy.go +++ /dev/null @@ -1,41 +0,0 @@ -// Package lagoon implements high-level functions for interacting with the -// Lagoon API. -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// Deploy interface contains methods for deploying branches and environments in lagoon. -type Deploy interface { - DeployEnvironmentPromote(ctx context.Context, deploy *schema.DeployEnvironmentPromoteInput, result *schema.DeployEnvironmentPromote) error - DeployEnvironmentLatest(ctx context.Context, deploy *schema.DeployEnvironmentLatestInput, result *schema.DeployEnvironmentLatest) error - DeployEnvironmentPullrequest(ctx context.Context, deploy *schema.DeployEnvironmentPullrequestInput, result *schema.DeployEnvironmentPullrequest) error - DeployEnvironmentBranch(ctx context.Context, deploy *schema.DeployEnvironmentBranchInput, result *schema.DeployEnvironmentBranch) error -} - -// DeployLatest deploys the latest environment. -func DeployLatest(ctx context.Context, deploy *schema.DeployEnvironmentLatestInput, m Deploy) (*schema.DeployEnvironmentLatest, error) { - result := schema.DeployEnvironmentLatest{} - return &result, m.DeployEnvironmentLatest(ctx, deploy, &result) -} - -// DeployPullRequest deploys a pull request. -func DeployPullRequest(ctx context.Context, deploy *schema.DeployEnvironmentPullrequestInput, m Deploy) (*schema.DeployEnvironmentPullrequest, error) { - result := schema.DeployEnvironmentPullrequest{} - return &result, m.DeployEnvironmentPullrequest(ctx, deploy, &result) -} - -// DeployPromote promotes one environment into a new environment. -func DeployPromote(ctx context.Context, deploy *schema.DeployEnvironmentPromoteInput, m Deploy) (*schema.DeployEnvironmentPromote, error) { - result := schema.DeployEnvironmentPromote{} - return &result, m.DeployEnvironmentPromote(ctx, deploy, &result) -} - -// DeployBranch deploys a branch. -func DeployBranch(ctx context.Context, deploy *schema.DeployEnvironmentBranchInput, m Deploy) (*schema.DeployEnvironmentBranch, error) { - result := schema.DeployEnvironmentBranch{} - return &result, m.DeployEnvironmentBranch(ctx, deploy, &result) -} diff --git a/internal/lagoon/deploytarget.go b/internal/lagoon/deploytarget.go deleted file mode 100644 index ac01987b..00000000 --- a/internal/lagoon/deploytarget.go +++ /dev/null @@ -1,35 +0,0 @@ -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -type DeployTargets interface { - AddDeployTarget(ctx context.Context, in *schema.AddDeployTargetInput, out *schema.AddDeployTargetResponse) error - UpdateDeployTarget(ctx context.Context, in *schema.UpdateDeployTargetInput, out *schema.UpdateDeployTargetResponse) error - DeleteDeployTarget(ctx context.Context, in *schema.DeleteDeployTargetInput, out *schema.DeleteDeployTargetResponse) error - ListDeployTargets(ctx context.Context, out *[]schema.DeployTarget) error -} - -func AddDeployTarget(ctx context.Context, in *schema.AddDeployTargetInput, out DeployTargets) (*schema.AddDeployTargetResponse, error) { - response := schema.AddDeployTargetResponse{} - return &response, out.AddDeployTarget(ctx, in, &response) -} - -func UpdateDeployTarget(ctx context.Context, in *schema.UpdateDeployTargetInput, out DeployTargets) (*schema.UpdateDeployTargetResponse, error) { - response := schema.UpdateDeployTargetResponse{} - return &response, out.UpdateDeployTarget(ctx, in, &response) -} - -func DeleteDeployTarget(ctx context.Context, in *schema.DeleteDeployTargetInput, out DeployTargets) (*schema.DeleteDeployTargetResponse, error) { - response := schema.DeleteDeployTargetResponse{} - return &response, out.DeleteDeployTarget(ctx, in, &response) -} - -// ListDeployTargets gets info of deploytargets in lagoon. -func ListDeployTargets(ctx context.Context, out DeployTargets) (*[]schema.DeployTarget, error) { - deploytargets := []schema.DeployTarget{} - return &deploytargets, out.ListDeployTargets(ctx, &deploytargets) -} diff --git a/internal/lagoon/deploytargetconfig.go b/internal/lagoon/deploytargetconfig.go deleted file mode 100644 index 35c5ddf5..00000000 --- a/internal/lagoon/deploytargetconfig.go +++ /dev/null @@ -1,34 +0,0 @@ -// Package lagoon implements high-level functions for interacting with the -// Lagoon API. -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// DeployTargetConfigs interface contains methods for getting info on deploytarget configs. -type DeployTargetConfigs interface { - DeployTargetConfigsByProjectID(ctx context.Context, project int, deployTargets *[]schema.DeployTargetConfig) error - UpdateDeployTargetConfiguration(ctx context.Context, in *schema.UpdateDeployTargetConfigInput, deployTargets *schema.DeployTargetConfig) error - DeleteDeployTargetConfiguration(ctx context.Context, id int, project int, deployTargets *schema.DeleteDeployTargetConfig) error -} - -// GetDeployTargetConfigs gets deploytarget configs for a specific project. -func GetDeployTargetConfigs(ctx context.Context, project int, dtc DeployTargetConfigs) (*[]schema.DeployTargetConfig, error) { - deployTargets := []schema.DeployTargetConfig{} - return &deployTargets, dtc.DeployTargetConfigsByProjectID(ctx, project, &deployTargets) -} - -// UpdateDeployTargetConfiguration adds a deploytarget config to a specific project. -func UpdateDeployTargetConfiguration(ctx context.Context, in *schema.UpdateDeployTargetConfigInput, dtc DeployTargetConfigs) (*schema.DeployTargetConfig, error) { - deployTarget := schema.DeployTargetConfig{} - return &deployTarget, dtc.UpdateDeployTargetConfiguration(ctx, in, &deployTarget) -} - -// DeleteDeployTargetConfiguration deletes a deploytarget config from a specific project. -func DeleteDeployTargetConfiguration(ctx context.Context, id int, project int, dtc DeployTargetConfigs) (*schema.DeleteDeployTargetConfig, error) { - deployTarget := schema.DeleteDeployTargetConfig{} - return &deployTarget, dtc.DeleteDeployTargetConfiguration(ctx, id, project, &deployTarget) -} diff --git a/internal/lagoon/environments.go b/internal/lagoon/environments.go deleted file mode 100644 index 037ce95d..00000000 --- a/internal/lagoon/environments.go +++ /dev/null @@ -1,27 +0,0 @@ -// Package lagoon implements high-level functions for interacting with the -// Lagoon API. -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// Environments interface contains methods for getting info on environments. -type Environments interface { - BackupsForEnvironmentByName(context.Context, string, uint, *schema.Environment) error - AddRestore(context.Context, string, *schema.Restore) error -} - -// GetBackupsForEnvironmentByName gets backup info in lagoon for specific environment. -func GetBackupsForEnvironmentByName(ctx context.Context, name string, project uint, e Environments) (*schema.Environment, error) { - environment := schema.Environment{} - return &environment, e.BackupsForEnvironmentByName(ctx, name, project, &environment) -} - -// AddBackupRestore adds a backup restore based on backup ID. -func AddBackupRestore(ctx context.Context, backupID string, e Environments) (*schema.Restore, error) { - restore := schema.Restore{} - return &restore, e.AddRestore(ctx, backupID, &restore) -} diff --git a/internal/lagoon/import.go b/internal/lagoon/import.go index 22bd6d16..46f87510 100644 --- a/internal/lagoon/import.go +++ b/internal/lagoon/import.go @@ -9,7 +9,7 @@ import ( "os" "github.com/uselagoon/lagoon-cli/internal/schema" - "github.com/uselagoon/lagoon-cli/pkg/api" + api "github.com/uselagoon/machinery/api/schema" ) // ErrExist indicates that an attempt was made to create an object that already diff --git a/internal/lagoon/import_test.go b/internal/lagoon/import_test.go index 5a31b748..1f65f1fd 100644 --- a/internal/lagoon/import_test.go +++ b/internal/lagoon/import_test.go @@ -11,7 +11,7 @@ import ( "github.com/uselagoon/lagoon-cli/internal/lagoon" "github.com/uselagoon/lagoon-cli/internal/mock" "github.com/uselagoon/lagoon-cli/internal/schema" - "github.com/uselagoon/lagoon-cli/pkg/api" + api "github.com/uselagoon/machinery/api/schema" ) // importCalls stores arrays of expected import calls associated with a given diff --git a/internal/lagoon/me.go b/internal/lagoon/me.go deleted file mode 100644 index 1863dc38..00000000 --- a/internal/lagoon/me.go +++ /dev/null @@ -1,20 +0,0 @@ -// Package lagoon implements high-level functions for interacting with the -// Lagoon API. -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// Me interface contains methods for getting info on the current user of lagoon. -type Me interface { - Me(ctx context.Context, user *schema.User) error -} - -// GetMeInfo gets info on the current user of lagoon. -func GetMeInfo(ctx context.Context, m Me) (*schema.User, error) { - user := schema.User{} - return &user, m.Me(ctx, &user) -} diff --git a/internal/lagoon/me_test.go b/internal/lagoon/me_test.go deleted file mode 100644 index 0e0fec6a..00000000 --- a/internal/lagoon/me_test.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:generate mockgen -source=me.go -destination ../mock/mock_me.go -package mock -package lagoon_test - -import ( - "context" - "testing" - - "github.com/golang/mock/gomock" - "github.com/uselagoon/lagoon-cli/internal/mock" - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -type meCalls struct { - Users []schema.User -} - -func TestGetMeInfo(t *testing.T) { - var testCases = map[string]struct { - expect *meCalls - }{ - "simple": {expect: &meCalls{ - Users: []schema.User{}, - }}, - } - for name, tc := range testCases { - t.Run(name, func(tt *testing.T) { - ctx := context.Background() - // set up the mock me - ctrl := gomock.NewController(tt) - defer ctrl.Finish() - me := mock.NewMockMe(ctrl) - // use the provided meCalls to set the expectations - for i := range tc.expect.Users { - me.EXPECT().Me(ctx, &tc.expect.Users[i]) - } - }) - } -} diff --git a/internal/lagoon/notifications.go b/internal/lagoon/notifications.go index 12e6fd7a..958c48d0 100644 --- a/internal/lagoon/notifications.go +++ b/internal/lagoon/notifications.go @@ -16,32 +16,6 @@ type Notification interface { AddNotificationMicrosoftTeams(ctx context.Context, input *schema.AddNotificationMicrosoftTeamsInput, result *schema.NotificationMicrosoftTeams) error AddNotificationSlack(ctx context.Context, input *schema.AddNotificationSlackInput, result *schema.NotificationSlack) error AddNotificationToProject(context.Context, *schema.AddNotificationToProjectInput, *schema.Project) error - - RemoveNotificationFromProject(context.Context, *schema.RemoveNotificationFromProjectInput, *schema.Project) error - - DeleteNotificationSlack(ctx context.Context, name string, project *schema.DeleteNotification) error - DeleteNotificationRocketChat(ctx context.Context, name string, project *schema.DeleteNotification) error - DeleteNotificationMicrosoftTeams(ctx context.Context, name string, project *schema.DeleteNotification) error - DeleteNotificationEmail(ctx context.Context, name string, project *schema.DeleteNotification) error - DeleteNotificationWebhook(ctx context.Context, name string, project *schema.DeleteNotification) error - - UpdateNotificationWebhook(ctx context.Context, input *schema.UpdateNotificationWebhookInput, result *schema.NotificationWebhook) error - UpdateNotificationEmail(ctx context.Context, input *schema.UpdateNotificationEmailInput, result *schema.NotificationEmail) error - UpdateNotificationRocketChat(ctx context.Context, input *schema.UpdateNotificationRocketChatInput, result *schema.NotificationRocketChat) error - UpdateNotificationMicrosoftTeams(ctx context.Context, input *schema.UpdateNotificationMicrosoftTeamsInput, result *schema.NotificationMicrosoftTeams) error - UpdateNotificationSlack(ctx context.Context, input *schema.UpdateNotificationSlackInput, result *schema.NotificationSlack) error - - GetAllNotificationEmail(ctx context.Context, project *[]schema.Project) error - GetAllNotificationWebhook(ctx context.Context, project *[]schema.Project) error - GetAllNotificationMicrosoftTeams(ctx context.Context, project *[]schema.Project) error - GetAllNotificationSlack(ctx context.Context, project *[]schema.Project) error - GetAllNotificationRocketChat(ctx context.Context, project *[]schema.Project) error - - GetProjectNotificationSlack(ctx context.Context, name string, project *schema.Project) error - GetProjectNotificationRocketChat(ctx context.Context, name string, project *schema.Project) error - GetProjectNotificationMicrosoftTeams(ctx context.Context, name string, project *schema.Project) error - GetProjectNotificationEmail(ctx context.Context, name string, project *schema.Project) error - GetProjectNotificationWebhook(ctx context.Context, name string, project *schema.Project) error } // AddNotificationWebhook adds a notification. @@ -79,129 +53,3 @@ func AddNotificationToProject(ctx context.Context, input *schema.AddNotification result := schema.Project{} return &result, n.AddNotificationToProject(ctx, input, &result) } - -// RemoveNotificationFromProject removes a notification from a project. -func RemoveNotificationFromProject(ctx context.Context, input *schema.RemoveNotificationFromProjectInput, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.RemoveNotificationFromProject(ctx, input, &result) -} - -// UpdateNotificationWebhook updates a notification. -func UpdateNotificationWebhook(ctx context.Context, input *schema.UpdateNotificationWebhookInput, n Notification) (*schema.NotificationWebhook, error) { - result := schema.NotificationWebhook{} - return &result, n.UpdateNotificationWebhook(ctx, input, &result) -} - -// UpdateNotificationEmail updates a notification. -func UpdateNotificationEmail(ctx context.Context, input *schema.UpdateNotificationEmailInput, n Notification) (*schema.NotificationEmail, error) { - result := schema.NotificationEmail{} - return &result, n.UpdateNotificationEmail(ctx, input, &result) -} - -// UpdateNotificationRocketChat updates a notification. -func UpdateNotificationRocketChat(ctx context.Context, input *schema.UpdateNotificationRocketChatInput, n Notification) (*schema.NotificationRocketChat, error) { - result := schema.NotificationRocketChat{} - return &result, n.UpdateNotificationRocketChat(ctx, input, &result) -} - -// UpdateNotificationMicrosoftTeams updates a notification. -func UpdateNotificationMicrosoftTeams(ctx context.Context, input *schema.UpdateNotificationMicrosoftTeamsInput, n Notification) (*schema.NotificationMicrosoftTeams, error) { - result := schema.NotificationMicrosoftTeams{} - return &result, n.UpdateNotificationMicrosoftTeams(ctx, input, &result) -} - -// UpdateNotificationSlack updates a notification. -func UpdateNotificationSlack(ctx context.Context, input *schema.UpdateNotificationSlackInput, n Notification) (*schema.NotificationSlack, error) { - result := schema.NotificationSlack{} - return &result, n.UpdateNotificationSlack(ctx, input, &result) -} - -// GetAllNotificationEmail gets all notifications of type. -func GetAllNotificationEmail(ctx context.Context, n Notification) (*[]schema.Project, error) { - result := []schema.Project{} - return &result, n.GetAllNotificationEmail(ctx, &result) -} - -// GetAllNotificationWebhook gets all notifications of type. -func GetAllNotificationWebhook(ctx context.Context, n Notification) (*[]schema.Project, error) { - result := []schema.Project{} - return &result, n.GetAllNotificationWebhook(ctx, &result) -} - -// GetAllNotificationSlack gets all notifications of type. -func GetAllNotificationSlack(ctx context.Context, n Notification) (*[]schema.Project, error) { - result := []schema.Project{} - return &result, n.GetAllNotificationSlack(ctx, &result) -} - -// GetAllNotificationRocketChat gets all notifications of type. -func GetAllNotificationRocketChat(ctx context.Context, n Notification) (*[]schema.Project, error) { - result := []schema.Project{} - return &result, n.GetAllNotificationRocketChat(ctx, &result) -} - -// GetAllNotificationMicrosoftTeams gets all notifications of type. -func GetAllNotificationMicrosoftTeams(ctx context.Context, n Notification) (*[]schema.Project, error) { - result := []schema.Project{} - return &result, n.GetAllNotificationMicrosoftTeams(ctx, &result) -} - -// GetProjectNotificationEmail gets all notifications of type in project. -func GetProjectNotificationEmail(ctx context.Context, name string, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.GetProjectNotificationEmail(ctx, name, &result) -} - -// GetProjectNotificationWebhook gets all notifications of type in project. -func GetProjectNotificationWebhook(ctx context.Context, name string, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.GetProjectNotificationWebhook(ctx, name, &result) -} - -// GetProjectNotificationRocketChat gets all notifications of type in project. -func GetProjectNotificationRocketChat(ctx context.Context, name string, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.GetProjectNotificationRocketChat(ctx, name, &result) -} - -// GetProjectNotificationSlack gets all notifications of type in project. -func GetProjectNotificationSlack(ctx context.Context, name string, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.GetProjectNotificationSlack(ctx, name, &result) -} - -// GetProjectNotificationMicrosoftTeams gets all notifications of type in project. -func GetProjectNotificationMicrosoftTeams(ctx context.Context, name string, n Notification) (*schema.Project, error) { - result := schema.Project{} - return &result, n.GetProjectNotificationMicrosoftTeams(ctx, name, &result) -} - -// DeleteNotificationEmail deletes notification. -func DeleteNotificationEmail(ctx context.Context, name string, n Notification) (*schema.DeleteNotification, error) { - result := schema.DeleteNotification{} - return &result, n.DeleteNotificationEmail(ctx, name, &result) -} - -// DeleteNotificationWebhook deletes notification. -func DeleteNotificationWebhook(ctx context.Context, name string, n Notification) (*schema.DeleteNotification, error) { - result := schema.DeleteNotification{} - return &result, n.DeleteNotificationWebhook(ctx, name, &result) -} - -// DeleteNotificationRocketChat deletes notification. -func DeleteNotificationRocketChat(ctx context.Context, name string, n Notification) (*schema.DeleteNotification, error) { - result := schema.DeleteNotification{} - return &result, n.DeleteNotificationRocketChat(ctx, name, &result) -} - -// DeleteNotificationSlack deletes notification. -func DeleteNotificationSlack(ctx context.Context, name string, n Notification) (*schema.DeleteNotification, error) { - result := schema.DeleteNotification{} - return &result, n.DeleteNotificationSlack(ctx, name, &result) -} - -// DeleteNotificationMicrosoftTeams deletes notification. -func DeleteNotificationMicrosoftTeams(ctx context.Context, name string, n Notification) (*schema.DeleteNotification, error) { - result := schema.DeleteNotification{} - return &result, n.DeleteNotificationMicrosoftTeams(ctx, name, &result) -} diff --git a/internal/lagoon/projects.go b/internal/lagoon/projects.go deleted file mode 100644 index b236ca5f..00000000 --- a/internal/lagoon/projects.go +++ /dev/null @@ -1,34 +0,0 @@ -// Package lagoon implements high-level functions for interacting with the -// Lagoon API. -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// Projects interface contains methods for getting info on projects. -type Projects interface { - MinimalProjectByName(ctx context.Context, name string, project *schema.Project) error - ProjectByNameMetadata(ctx context.Context, name string, project *schema.ProjectMetadata) error - SSHEndpointsByProject(ctx context.Context, name string, project *schema.Project) error -} - -// GetMinimalProjectByName gets info of projects in lagoon that have matching metadata. -func GetMinimalProjectByName(ctx context.Context, name string, p Projects) (*schema.Project, error) { - project := schema.Project{} - return &project, p.MinimalProjectByName(ctx, name, &project) -} - -// GetProjectMetadata gets the metadata key:values for a lagoon project. -func GetProjectMetadata(ctx context.Context, name string, p Projects) (*schema.ProjectMetadata, error) { - project := schema.ProjectMetadata{} - return &project, p.ProjectByNameMetadata(ctx, name, &project) -} - -// GetSSHEndpointsByProject gets info of projects in lagoon that have matching metadata. -func GetSSHEndpointsByProject(ctx context.Context, name string, p Projects) (*schema.Project, error) { - project := schema.Project{} - return &project, p.SSHEndpointsByProject(ctx, name, &project) -} diff --git a/internal/lagoon/variables.go b/internal/lagoon/variables.go deleted file mode 100644 index e07c7be4..00000000 --- a/internal/lagoon/variables.go +++ /dev/null @@ -1,29 +0,0 @@ -package lagoon - -import ( - "context" - - "github.com/uselagoon/lagoon-cli/internal/schema" -) - -type Variables interface { - AddOrUpdateEnvVariableByName(ctx context.Context, in *schema.EnvVariableByNameInput, envvar *schema.UpdateEnvVarResponse) error - DeleteEnvVariableByName(ctx context.Context, in *schema.DeleteEnvVariableByNameInput, envvar *schema.DeleteEnvVarResponse) error - GetEnvVariablesByProjectEnvironmentName(ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, envvar *[]schema.EnvKeyValue) error -} - -func AddOrUpdateEnvVariableByName(ctx context.Context, in *schema.EnvVariableByNameInput, v Variables) (*schema.UpdateEnvVarResponse, error) { - envvar := schema.UpdateEnvVarResponse{} - return &envvar, v.AddOrUpdateEnvVariableByName(ctx, in, &envvar) -} - -func DeleteEnvVariableByName(ctx context.Context, in *schema.DeleteEnvVariableByNameInput, v Variables) (*schema.DeleteEnvVarResponse, error) { - envvar := schema.DeleteEnvVarResponse{} - return &envvar, v.DeleteEnvVariableByName(ctx, in, &envvar) -} - -// ListEnvVars gets info of envvars in lagoon. -func GetEnvVariablesByProjectEnvironmentName(ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, v Variables) (*[]schema.EnvKeyValue, error) { - envvar := []schema.EnvKeyValue{} - return &envvar, v.GetEnvVariablesByProjectEnvironmentName(ctx, in, &envvar) -} diff --git a/internal/mock/mock_me.go b/internal/mock/mock_me.go deleted file mode 100644 index 9d5479cf..00000000 --- a/internal/mock/mock_me.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: me.go - -// Package mock is a generated GoMock package. -package mock - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - schema "github.com/uselagoon/lagoon-cli/internal/schema" -) - -// MockMe is a mock of Me interface. -type MockMe struct { - ctrl *gomock.Controller - recorder *MockMeMockRecorder -} - -// MockMeMockRecorder is the mock recorder for MockMe. -type MockMeMockRecorder struct { - mock *MockMe -} - -// NewMockMe creates a new mock instance. -func NewMockMe(ctrl *gomock.Controller) *MockMe { - mock := &MockMe{ctrl: ctrl} - mock.recorder = &MockMeMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockMe) EXPECT() *MockMeMockRecorder { - return m.recorder -} - -// Me mocks base method. -func (m *MockMe) Me(ctx context.Context, user *schema.User) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Me", ctx, user) - ret0, _ := ret[0].(error) - return ret0 -} - -// Me indicates an expected call of Me. -func (mr *MockMeMockRecorder) Me(ctx, user interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Me", reflect.TypeOf((*MockMe)(nil).Me), ctx, user) -} diff --git a/internal/schema/config.go b/internal/schema/config.go index 5abcbf01..f435dc22 100644 --- a/internal/schema/config.go +++ b/internal/schema/config.go @@ -6,7 +6,7 @@ import ( "fmt" "unicode" - "github.com/uselagoon/lagoon-cli/pkg/api" + api "github.com/uselagoon/machinery/api/schema" "sigs.k8s.io/yaml" ) diff --git a/internal/schema/environment.go b/internal/schema/environment.go index be20366f..2fe145d4 100644 --- a/internal/schema/environment.go +++ b/internal/schema/environment.go @@ -1,6 +1,8 @@ package schema -import "github.com/uselagoon/lagoon-cli/pkg/api" +import ( + api "github.com/uselagoon/machinery/api/schema" +) // AddEnvironmentInput is based on the input to // addOrUpdateEnvironment. diff --git a/internal/schema/group.go b/internal/schema/group.go index 1e651968..6f8fbfbb 100644 --- a/internal/schema/group.go +++ b/internal/schema/group.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/google/uuid" - "github.com/uselagoon/lagoon-cli/pkg/api" + api "github.com/uselagoon/machinery/api/schema" ) // AddGroupInput is based on the input to addGroup. diff --git a/internal/schema/project.go b/internal/schema/project.go index 37b2aa35..9ff8d7cf 100644 --- a/internal/schema/project.go +++ b/internal/schema/project.go @@ -1,6 +1,8 @@ package schema -import "github.com/uselagoon/lagoon-cli/pkg/api" +import ( + api "github.com/uselagoon/machinery/api/schema" +) // AddProjectInput is based on the Lagoon API type. type AddProjectInput struct { diff --git a/internal/schema/sshKey.go b/internal/schema/sshKey.go index 4866d55a..222419a5 100644 --- a/internal/schema/sshKey.go +++ b/internal/schema/sshKey.go @@ -1,6 +1,8 @@ package schema -import "github.com/uselagoon/lagoon-cli/pkg/api" +import ( + api "github.com/uselagoon/machinery/api/schema" +) // SSHKey is the basic SSH key information, used by both config and API data. // @TODO: once Lagoon API returns proper TZ, fix up `Created` to time.Time. diff --git a/pkg/api/README.md b/pkg/api/README.md deleted file mode 100644 index 01aca8f3..00000000 --- a/pkg/api/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# WIP - -This package is still very much a WIP - -## Lagoon API - -This package is intended to be moved into `https://github.com/uselagoon/lagoon/` at some stage, but for now is bundled with the `lagoon-cli` - -It is to be similar, but not identical to `node-packages/commons/src/api.js` diff --git a/pkg/api/backups.go b/pkg/api/backups.go deleted file mode 100644 index c1f78309..00000000 --- a/pkg/api/backups.go +++ /dev/null @@ -1,185 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// AddBackup . -func (api *Interface) AddBackup(backup AddBackup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($id: Int, $environment: Int!, $source: String!, $backupId: String!, $created: String!) { - addBackup(input: { - id: $id - environment: $environment - source: $source - backupId: $backupId - created: $created - }) { - ...Backup - } - }` + backupFragment) - generateVars(req, backup) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addBackup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteBackup . -func (api *Interface) DeleteBackup(backup DeleteBackup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($backupId: String!) { - deleteBackup(input: { - backupId: $backupId - }) - }`) - generateVars(req, backup) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteBackup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateRestore . -func (api *Interface) UpdateRestore(update UpdateRestore) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($backupId: String!, $patch: UpdateRestorePatchInput!) { - updateRestore(input: { - backupId: $backupId - patch: $patch - }) { - ...Restore - } - }` + restoreFragment) - generateVars(req, update) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateRestore"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetAllEnvironmentBackups . -func (api *Interface) GetAllEnvironmentBackups() ([]byte, error) { - req := graphql.NewRequest(` - query { - allEnvironments { - id - name - openshiftProjectName - project { - name - } - backups { - ...Backup - } - } - }` + backupFragment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["allEnvironments"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetEnvironmentBackups . -func (api *Interface) GetEnvironmentBackups(backups EnvironmentBackups) ([]byte, error) { - req := graphql.NewRequest(` - query environmentByOpenshiftProjectName($openshiftProjectName: String!) { - environmentByOpenshiftProjectName(openshiftProjectName: $openshiftProjectName) { - id - name - openshiftProjectName - project { - name - } - backups { - id - backupId - source - created - } - } - }`) - generateVars(req, backups) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["environmentByOpenshiftProjectName"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/api/environments.go b/pkg/api/environments.go deleted file mode 100644 index 67fd111b..00000000 --- a/pkg/api/environments.go +++ /dev/null @@ -1,200 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// GetEnvironmentByName . -func (api *Interface) GetEnvironmentByName(environment EnvironmentByName, fragment string) ([]byte, error) { - if fragment == "" { - fragment = environmentByNameFragment - } - req := graphql.NewRequest(` - query ($name: String!, $project: Int!) { - environmentByName(name: $name, project: $project) { - ...Environment - } - }` + fragment) - generateVars(req, environment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["environmentByName"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddOrUpdateEnvironment . -func (api *Interface) AddOrUpdateEnvironment(environment AddUpdateEnvironment) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!, $project: Int!, $deployType: DeployType!, $deployBaseRef: String!, $deployHeadRef: String, $deployTitle: String, $environmentType: EnvType!, $openshiftProjectName: String!) { - addOrUpdateEnvironment(input: { - name: $name, - project: $project, - deployType: $deployType, - deployBaseRef: $deployBaseRef, - deployHeadRef: $deployHeadRef, - deployTitle: $deployTitle, - environmentType: $environmentType, - openshiftProjectName: $openshiftProjectName - }) { - id - name - project { - name - } - deployType - environmentType - openshiftProjectName - envVariables { - name - value - scope - } - } - }`) - req.Var("name", environment.Name) - generateVars(req, environment.Patch) - // req.Var("project", environment.Patch.Project) - // req.Var("deployType", environment.Patch.DeployType) - // req.Var("deployBaseRef", environment.Patch.DeployBaseRef) - // req.Var("deployHeadRef", environment.Patch.DeployHeadRef) - // req.Var("deployTitle", environment.Patch.DeployTitle) - // req.Var("environmentType", environment.Patch.EnvironmentType) - // req.Var("openshiftProjectName", environment.Patch.OpenshiftProjectName) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addOrUpdateEnvironment"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateEnvironment . -func (api *Interface) UpdateEnvironment(environment UpdateEnvironment) ([]byte, error) { - req := graphql.NewRequest(` - mutation { - updateEnvironment(input: { - id: ${environmentId}, - patch: ${patch} - }) { - id - name - } - }`) - generateVars(req, environment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateEnvironment"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteEnvironment . -func (api *Interface) DeleteEnvironment(environment DeleteEnvironment) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!, $project: String!, $execute: Boolean) { - deleteEnvironment(input: { - name: $name - project: $project - execute: $execute - }) - }`) - generateVars(req, environment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteEnvironment"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// SetEnvironmentServices . -func (api *Interface) SetEnvironmentServices(environment SetEnvironmentServices) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($environment: Int!, $services: [String]!) { - setEnvironmentServices(input: { - environment: $environment - services: $services - }) { - id - name - } - }`) - generateVars(req, environment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["setEnvironmentServices"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/api/fragments.go b/pkg/api/fragments.go deleted file mode 100644 index 9adab6ed..00000000 --- a/pkg/api/fragments.go +++ /dev/null @@ -1,99 +0,0 @@ -package api - -var deploymentFragment = `fragment Deployment on Deployment { - id - name - status - created - started - completed - remoteId - environment { - name - } -}` - -var taskFragment = `fragment Task on Task { - id - name - status - created - started - completed - remoteId - environment { - name - } -}` - -var projectFragment = `fragment Project on Project { - id - name - gitUrl - privateKey -}` - -var restoreFragment = `fragment Restore on Restore { - id - status - created - restoreLocation - backupId -}` - -var backupFragment = `fragment Backup on Backup { - id - environment { - id - } - backupId - source - created -}` - -var groupFragment = `fragment Group on Group { - id - name -}` - -var userFragment = `fragment User on User { - id - email - firstName - lastName - gitlabId - sshKeys { - id - name - } -}` - -var sshKeyFragment = `fragment SshKey on SshKey { - id - name - keyValue - keyType -}` - -var notificationsRocketChatFragment = `fragment Notification on NotificationRocketChat { - webhook - channel -}` - -var notificationsSlackFragment = `fragment Notification on NotificationSlack { - webhook - channel -}` - -var environmentByNameFragment = `fragment Environment on Environment { - id - name - route - routes - deployType - environmentType - openshiftProjectName - updated - created - deleted -}` diff --git a/pkg/api/groups.go b/pkg/api/groups.go deleted file mode 100644 index 1c0266e0..00000000 --- a/pkg/api/groups.go +++ /dev/null @@ -1,278 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// AddGroup . -func (api *Interface) AddGroup(group AddGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!) { - addGroup(input: { - name: $name - }) { - ...Group - } - }` + groupFragment) - generateVars(req, group) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddGroupWithParent . -func (api *Interface) AddGroupWithParent(group AddGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!, $parentGroupName: String) { - addGroup(input: { - name: $name - parentGroup: { name: $parentGroupName } - }) { - ...Group - } - }` + groupFragment) - req.Var("name", group.Name) - req.Var("parentGroupName", group.ParentGroup.Name) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateGroup . -func (api *Interface) UpdateGroup(group UpdateGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!, $patch: UpdateGroupPatchInput!) { - updateGroup(input: { - group: { - name: $name - } - patch: $patch - }) { - ...Group - } - }` + groupFragment) - req.Var("name", group.Group.Name) - req.Var("patch", group.Patch) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteGroup . -func (api *Interface) DeleteGroup(group AddGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!) { - deleteGroup(input: { - group: { - name: $name - } - }) - }`) - generateVars(req, group) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddUserToGroup . -func (api *Interface) AddUserToGroup(user AddUserToGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($userEmail: String!, $groupName: String!, $role: GroupRole!) { - addUserToGroup(input: { - user: { email: $userEmail } - group: { name: $groupName } - role: $role - }) { - ...Group - } - }` + groupFragment) - req.Var("userEmail", user.User.Email) - req.Var("groupName", user.Group) - req.Var("role", user.Role) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addUserToGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddGroupToProject . -func (api *Interface) AddGroupToProject(group ProjectToGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($project: String!, $group: String!) { - addUserToGroup(input: { - project: { name: $project} - groups: [{name: $group}] - }) { - ...Project - } - }` + projectFragment) - generateVars(req, group) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addUserToGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// RemoveGroupFromProject . -func (api *Interface) RemoveGroupFromProject(group ProjectToGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($project: String!, $group: String!) { - removeGroupsFromProject(input: { - project: { name: $project} - groups: [{name: $group}] - }) { - ...Project - } - }` + projectFragment) - generateVars(req, group) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["removeGroupsFromProject"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// RemoveUserFromGroup . -func (api *Interface) RemoveUserFromGroup(user UserGroup) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($userEmail: String!, $groupName: String!) { - removeUserFromGroup(input: { - user: { email: $userEmail } - group: { name: $groupName } - }) { - ...Group - } - }` + groupFragment) - req.Var("userEmail", user.User.Email) - req.Var("groupName", user.Group) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["removeUserFromGroup"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/api/main.go b/pkg/api/main.go deleted file mode 100644 index e9a81770..00000000 --- a/pkg/api/main.go +++ /dev/null @@ -1,229 +0,0 @@ -package api - -import ( - "context" - "fmt" - "strings" - - "net/http" - "regexp" - - "crypto/tls" - "encoding/json" - "time" - - "github.com/golang-jwt/jwt" - "github.com/logrusorgru/aurora" - "github.com/machinebox/graphql" -) - -// Client struct -type Client interface { - // Assorted - RunQuery(*graphql.Request, interface{}) (interface{}, error) - Request(CustomRequest) ([]byte, error) - SanitizeGroupName(string) string - SanitizeProjectName(string) string - Debug(bool) - // Users - AddUser(User) ([]byte, error) - UpdateUser(UpdateUser) ([]byte, error) - DeleteUser(User) ([]byte, error) - GetUserBySSHKey(SSHKeyValue) ([]byte, error) - AddSSHKey(AddSSHKey) ([]byte, error) - DeleteSSHKey(DeleteSSHKey) ([]byte, error) - // Tasks - UpdateTask(UpdateTask) ([]byte, error) - // Backups - AddBackup(AddBackup) ([]byte, error) - DeleteBackup(DeleteBackup) ([]byte, error) - UpdateRestore(UpdateRestore) ([]byte, error) - GetAllEnvironmentBackups() ([]byte, error) - GetEnvironmentBackups(EnvironmentBackups) ([]byte, error) - // Groups - AddGroup(AddGroup) ([]byte, error) - AddGroupWithParent(AddGroup) ([]byte, error) - UpdateGroup(UpdateGroup) ([]byte, error) - DeleteGroup(AddGroup) ([]byte, error) - AddUserToGroup(AddUserToGroup) ([]byte, error) - AddGroupToProject(ProjectToGroup) ([]byte, error) - RemoveGroupFromProject(ProjectToGroup) ([]byte, error) - RemoveUserFromGroup(UserGroup) ([]byte, error) - // Environments - GetEnvironmentByName(EnvironmentByName, string) ([]byte, error) - AddOrUpdateEnvironment(AddUpdateEnvironment) ([]byte, error) - UpdateEnvironment(UpdateEnvironment) ([]byte, error) - DeleteEnvironment(DeleteEnvironment) ([]byte, error) - SetEnvironmentServices(SetEnvironmentServices) ([]byte, error) - // Projects - GetOpenShiftInfoForProject(Project) ([]byte, error) - AddProject(ProjectPatch, string) ([]byte, error) - UpdateProject(UpdateProject, string) ([]byte, error) - DeleteProject(Project) ([]byte, error) - GetProductionEnvironmentForProject(Project) ([]byte, error) - GetEnvironmentByOpenshiftProjectName(Environment) ([]byte, error) - GetProjectsByGitURL(Project) ([]byte, error) - GetProjectByName(Project, string) ([]byte, error) - GetAllProjects(string) ([]byte, error) - GetRocketChatInfoForProject(Project, string) ([]byte, error) - GetSlackInfoForProject(Project, string) ([]byte, error) - GetEnvironmentsForProject(Project) ([]byte, error) - GetDeploymentByRemoteID(Deployment) ([]byte, error) - AddDeployment(Deployment) ([]byte, error) - UpdateDeployment(UpdateDeployment) ([]byte, error) -} - -// Interface struct -type Interface struct { - token string - graphQLEndpoint string - debug bool - netClient *http.Client - graphqlClient *graphql.Client -} - -// CustomRequest . -type CustomRequest struct { - Query string - Variables map[string]interface{} - MappedResult string -} - -var netClient = &http.Client{ - Timeout: time.Second * time.Duration(10), -} - -// New creates an interface against an endpoint with the api using jwt signing key and audience -func New(tokenSigningKey string, jwtAudience string, graphQLEndpoint string) (Client, error) { - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - client := graphql.NewClient(graphQLEndpoint) - - tokenString, tokenErr := getJWTToken(jwtAudience, tokenSigningKey) - return &Interface{ - graphQLEndpoint: graphQLEndpoint, - token: tokenString, - netClient: netClient, - graphqlClient: client, - }, tokenErr -} - -// NewWithToken creates an interface against an endpoint with the api using a jwt token -func NewWithToken(tokenString string, graphQLEndpoint string) (Client, error) { - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - client := graphql.NewClient(graphQLEndpoint) - return &Interface{ - token: tokenString, - graphQLEndpoint: graphQLEndpoint, - netClient: netClient, - graphqlClient: client, - }, nil -} - -func getJWTToken(tokenAudience string, tokenSigningKey string) (string, error) { - // generate a token with our claims - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "iat": int32(time.Now().Unix()), - "role": "admin", - "iss": "lagoon-commons", - "aud": "" + tokenAudience + "", - "sub": "lagoon-commons", - }) - // sign and get the complete encoded token as a string using the secret - tokenString, tokenErr := token.SignedString([]byte(tokenSigningKey)) - return tokenString, tokenErr -} - -// RunQuery run a graphql query against an api endpoint, return the result -func (api *Interface) RunQuery(graphQLQuery *graphql.Request, returnType interface{}) (interface{}, error) { - graphQLQuery.Header.Set("Cache-Control", "no-cache") - graphQLQuery.Header.Add("Authorization", "Bearer "+api.token) - // define a Context for the request - ctx := context.Background() - // run it and capture the response - err := api.graphqlClient.Run(ctx, graphQLQuery, &returnType) - return returnType, err -} - -// SanitizeGroupName . -func (api *Interface) SanitizeGroupName(name string) string { - return sanitizeName(name) -} - -// SanitizeProjectName . -func (api *Interface) SanitizeProjectName(name string) string { - return sanitizeName(name) -} - -// Debug . -func (api *Interface) Debug(debug bool) { - api.debug = debug -} - -func sanitizeName(name string) string { - var re = regexp.MustCompile(`[^a-zA-Z0-9-]`) - sanitizedName := re.ReplaceAllString(name, `$1-$2`) - return sanitizedName -} - -// Request . -func (api *Interface) Request(request CustomRequest) ([]byte, error) { - req := graphql.NewRequest(request.Query) - for varName, varValue := range request.Variables { - req.Var(string(varName), varValue) - } - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult[request.MappedResult]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - return jsonBytes, nil -} - -func generateVars(request *graphql.Request, jsonData interface{}) { - jsonString, _ := json.Marshal(jsonData) - var dat map[string]interface{} - if err := json.Unmarshal([]byte(jsonString), &dat); err != nil { - panic(err) - } - for varName, varValue := range dat { - request.Var(string(varName), varValue) - } -} - -// DebugData . -type DebugData struct { - Query string `json:"query"` - Vars []DebugVar `json:"variables"` -} - -// DebugVar . -type DebugVar struct { - Name string `json:"name"` - Value interface{} `json:"value"` -} - -// debug the query and variables that are sent for the request -func debugRequest(req *graphql.Request) { - data := DebugData{ - Query: req.Query(), - } - for n, v := range req.Vars() { - data.Vars = append(data.Vars, DebugVar{Name: n, Value: v}) - } - jsonData, _ := json.Marshal(data) - fmt.Printf("%s: %s\n", aurora.Yellow("Request"), strings.Replace(string(jsonData), "\\t", "", -1)) -} - -func debugResponse(resp []byte) { - fmt.Printf("%s: %s\n", aurora.Yellow("Response"), string(resp)) -} diff --git a/pkg/api/projects.go b/pkg/api/projects.go deleted file mode 100644 index 54a59853..00000000 --- a/pkg/api/projects.go +++ /dev/null @@ -1,548 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// GetOpenShiftInfoForProject . -func (api *Interface) GetOpenShiftInfoForProject(project Project) ([]byte, error) { - req := graphql.NewRequest(` - query ($project: String!) { - project:projectByName(name: $project) { - id - openshift { - name - consoleUrl - token - projectUser - routerPattern - } - gitUrl - deployTargetConfigs{ - deployTarget{ - id - name - token - } - } - privateKey - subfolder - openshiftProjectPattern - productionEnvironment - envVariables { - name - value - scope - } - } - }`) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddProject . -func (api *Interface) AddProject(project ProjectPatch, fragment string) ([]byte, error) { - if fragment == "" { - fragment = projectFragment - } - //@TODO: Make this use the actual AddProjectInput type instead of defining everything here - req := graphql.NewRequest(` - mutation ($name: String!, $gitUrl: String!, $openshift: Int!, $productionEnvironment: String!, - $id: Int, $privateKey: String, $subfolder: String, $openshiftProjectPattern: String, - $branches: String, $pullrequests: String, $availability: ProjectAvailability, $autoIdle: Int, $developmentEnvironmentsLimit: Int) { - addProject(input: { - name: $name, - gitUrl: $gitUrl, - openshift: $openshift, - productionEnvironment: $productionEnvironment, - id: $id, - privateKey: $privateKey, - subfolder: $subfolder, - openshiftProjectPattern: $openshiftProjectPattern, - branches: $branches, - pullrequests: $pullrequests, - availability: $availability, - autoIdle: $autoIdle, - developmentEnvironmentsLimit: $developmentEnvironmentsLimit - }) { - ...Project - } - }` + fragment) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addProject"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateProject . -func (api *Interface) UpdateProject(project UpdateProject, fragment string) ([]byte, error) { - if fragment == "" { - fragment = projectFragment - } - req := graphql.NewRequest(` - mutation ($id: Int!, $patch: UpdateProjectPatchInput!) { - updateProject(input: { - id: $id - patch: $patch - }) { - ...Project - } - }` + fragment) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateProject"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteProject . -func (api *Interface) DeleteProject(project Project) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!) { - deleteProject(input: { - project: $name - }) - }`) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteProject"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetProductionEnvironmentForProject . -func (api *Interface) GetProductionEnvironmentForProject(project Project) ([]byte, error) { - req := graphql.NewRequest(` - query ($name: String!) { - project:projectByName(name: $name){ - productionEnvironment - } - }`) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetEnvironmentByOpenshiftProjectName . -func (api *Interface) GetEnvironmentByOpenshiftProjectName(environment Environment) ([]byte, error) { - req := graphql.NewRequest(` - query { - environmentByOpenshiftProjectName(openshiftProjectName: "${openshiftProjectName}") { - id, - name, - project { - name - } - } - }`) - generateVars(req, environment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["environmentByOpenshiftProjectName"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetProjectsByGitURL . -func (api *Interface) GetProjectsByGitURL(project Project) ([]byte, error) { - req := graphql.NewRequest(` - query { - allProjects(gitUrl: "${gitUrl}") { - name - productionEnvironment - openshift { - consoleUrl - token - projectUser - routerPattern - } - } - }`) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["allProjects"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetProjectByName . -func (api *Interface) GetProjectByName(project Project, fragment string) ([]byte, error) { - if fragment == "" { - fragment = projectFragment - } - req := graphql.NewRequest(` - query ($name: String!){ - project:projectByName(name: $name) { - ...Project - } - }` + fragment) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetAllProjects . -func (api *Interface) GetAllProjects(fragment string) ([]byte, error) { - if fragment == "" { - fragment = projectFragment - } - req := graphql.NewRequest(` - query { - allProjects { - ...Project - } - }` + fragment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["allProjects"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetRocketChatInfoForProject . -func (api *Interface) GetRocketChatInfoForProject(project Project, fragment string) ([]byte, error) { - if fragment == "" { - fragment = notificationsRocketChatFragment - } - req := graphql.NewRequest(` - query ($name: String!) { - project:projectByName(name: $name) { - rocketchats: notifications(type: ROCKETCHAT) { - ...Notification - } - } - }` + fragment) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetSlackInfoForProject . -func (api *Interface) GetSlackInfoForProject(project Project, fragment string) ([]byte, error) { - if fragment == "" { - fragment = notificationsSlackFragment - } - req := graphql.NewRequest(` - query ($name: String!){ - project:projectByName(name: $name) { - slacks: notifications(type: SLACK) { - ...Notification - } - } - }` + fragment) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetEnvironmentsForProject . -func (api *Interface) GetEnvironmentsForProject(project Project) ([]byte, error) { - req := graphql.NewRequest(` - query ($name: String!){ - project:projectByName(name: $name){ - developmentEnvironmentsLimit - productionEnvironment - environments(includeDeleted:false) { name, environmentType } - } - }`) - generateVars(req, project) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["project"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetDeploymentByRemoteID . -func (api *Interface) GetDeploymentByRemoteID(deployment Deployment) ([]byte, error) { - req := graphql.NewRequest(` - query deploymentByRemoteId($id: String!) { - deploymentByRemoteId(id: $id) { - ...Deployment - } - }` + deploymentFragment) - generateVars(req, deployment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deploymentByRemoteId"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddDeployment . -func (api *Interface) AddDeployment(deployment Deployment) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!, $status: DeploymentStatusType!, $created: String!, $environment: Int!, $id: Int, $remoteId: String, $started: String, $completed: String) { - addDeployment(input: { - name: $name - status: $status - created: $created - environment: $environment - id: $id - remoteId: $remoteId - started: $started - completed: $completed - }) { - ...Deployment - } - }` + deploymentFragment) - generateVars(req, deployment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addDeployment"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateDeployment . -func (api *Interface) UpdateDeployment(deployment UpdateDeployment) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($id: Int!, $patch: UpdateDeploymentPatchInput!) { - updateDeployment(input: { - id: $id - patch: $patch - }) { - ...Deployment - } - }` + deploymentFragment) - generateVars(req, deployment) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateDeployment"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/api/tasks.go b/pkg/api/tasks.go deleted file mode 100644 index d16bae70..00000000 --- a/pkg/api/tasks.go +++ /dev/null @@ -1,41 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// UpdateTask . -func (api *Interface) UpdateTask(task UpdateTask) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($id: Int!, $patch: UpdateTaskPatchInput!) { - updateTask(input: { - id: $id - patch: $patch - }) { - ...Task - } - }` + taskFragment) - generateVars(req, task) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateTask"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/api/types.go b/pkg/api/types.go deleted file mode 100644 index b03956ff..00000000 --- a/pkg/api/types.go +++ /dev/null @@ -1,716 +0,0 @@ -package api - -// SSHKeyType . -type SSHKeyType string - -// . . -const ( - SSHRsa SSHKeyType = "SSH_RSA" - SSHEd25519 SSHKeyType = "SSH_ED25519" - SSHECDSA256 SSHKeyType = "ECDSA_SHA2_NISTP256" - SSHECDSA384 SSHKeyType = "ECDSA_SHA2_NISTP384" - SSHECDSA521 SSHKeyType = "ECDSA_SHA2_NISTP521" -) - -// DeployType . -type DeployType string - -// . . -const ( - Branch DeployType = "BRANCH" - PullRequest DeployType = "PULLREQUEST" - Promote DeployType = "PROMOTE" -) - -// EnvType . -type EnvType string - -// . . -const ( - ProductionEnv EnvType = "PRODUCTION" - DevelopmentEnv EnvType = "DEVELOPMENT" -) - -// NotificationType . -type NotificationType string - -// . . -const ( - SlackNotification NotificationType = "SLACK" - RocketChatNotification NotificationType = "ROCKETCHAT" - EmailNotification NotificationType = "EMAIL" - MicrosoftTeamsNotification NotificationType = "MICROSOFTTEAMS" - WebhookNotification NotificationType = "WEBHOOK" -) - -// DeploymentStatusType . -type DeploymentStatusType string - -// . . -const ( - NewDeploy DeploymentStatusType = "NEW" - PendingDeploy DeploymentStatusType = "PENDING" - RunningDeploy DeploymentStatusType = "RUNNING" - CancelledDeploy DeploymentStatusType = "CANCELLED" - ErrorDeploy DeploymentStatusType = "ERROR" - FailedDeploy DeploymentStatusType = "FAILED" - CompleteDeploy DeploymentStatusType = "COMPLETE" -) - -// EnvVariableType . -type EnvVariableType string - -// . . -const ( - ProjectVar EnvVariableType = "PROJECT" - EnvironmentVar EnvVariableType = "ENVIRONMENT" -) - -// EnvVariableScope . -type EnvVariableScope string - -// . . -const ( - BuildVar EnvVariableScope = "BUILD" - RuntimeVar EnvVariableScope = "RUNTIME" - GlobalVar EnvVariableScope = "GLOBAL" - InternalContainerRegistryVar EnvVariableScope = "INTERNAL_CONTAINER_REGISTRY" - ContainerRegistryVar EnvVariableScope = "CONTAINER_REGISTRY" -) - -// TaskStatusType . -type TaskStatusType string - -// . . -const ( - ActiveTask TaskStatusType = "ACTIVE" - SucceededTask TaskStatusType = "SUCCEEDED" - FailedTask TaskStatusType = "FAILED" -) - -// RestoreStatusType . -type RestoreStatusType string - -// Pending . -const ( - PendingRestore RestoreStatusType = "PENDING" - SuccessfulRestore RestoreStatusType = "SUCCESSFUL" - FailedRestore RestoreStatusType = "FAILED" -) - -// EnvOrderType . -type EnvOrderType string - -// . . -const ( - NameEnvOrder EnvOrderType = "NAME" - UpdatedEnvOrder EnvOrderType = "UPDATED" -) - -// ProjectOrderType . -type ProjectOrderType string - -// . . -const ( - NameProjectOrder ProjectOrderType = "NAME" - CreatedProjectOrder ProjectOrderType = "UPCREATEDDATED" -) - -// GroupRole . -type GroupRole string - -// Guest . -const ( - GuestRole GroupRole = "GUEST" - ReporterRole GroupRole = "REPORTER" - DeveloperRole GroupRole = "DEVELOPER" - MaintainerRole GroupRole = "MAINTAINER" - OwnerRole GroupRole = "OWNER" -) - -// File . -type File struct { - ID int `json:"id,omitempty"` - Filename string `json:"filename,omitempty"` - Download string `json:"download,omitempty"` - Created string `json:"created,omitempty"` -} - -// SSHKey . -type SSHKey struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - KeyValue string `json:"keyValue,omitempty"` - KeyType SSHKeyType `json:"keyType,omitempty"` - KeyFingerprint string `json:"keyFingerprint,omitempty"` -} - -// SSHKeyValue . -type SSHKeyValue string - -// User struct. -type User struct { - ID string `json:"id,omitempty"` - Email string `json:"email,omitempty"` - FirstName string `json:"firstName,omitempty"` - LastName string `json:"lastName,omitempty"` - Comment string `json:"comment,omitempty"` - GitlabID int `json:"gitlabId,omitempty"` - SSHKeys []SSHKey `json:"sshKeys,omitempty"` - Groups []Group `json:"groups,omitempty"` -} - -// GroupMembership . -type GroupMembership struct { - User User `json:"user"` - Role GroupRole `json:"role"` -} - -// Group struct. -type Group struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Groups []Group `json:"groups,omitempty"` - Members string `json:"members,omitempty"` -} - -// Openshift struct. -type Openshift struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - ConsoleURL string `json:"consoleUrl,omitempty"` - Token string `json:"token,omitempty"` - RouterPattern string `json:"routerPattern,omitempty"` - ProjectUser string `json:"projectUser,omitempty"` - SSHHost string `json:"sshHost,omitempty"` - SSHPort string `json:"sshPort,omitempty"` - Created string `json:"created,omitempty"` -} - -// NotificationRocketChat struct. -type NotificationRocketChat struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Webhook string `json:"webhook,omitempty"` - Channel string `json:"channel,omitempty"` -} - -// NotificationSlack struct. -type NotificationSlack struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Webhook string `json:"webhook,omitempty"` - Channel string `json:"channel,omitempty"` -} - -// UnassignedNotification struct. -type UnassignedNotification struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Type string `json:"type,omitempty"` -} - -// UpdateProject struct. -type UpdateProject struct { - ID int `json:"id"` - Patch ProjectPatch `json:"patch"` -} - -// DeleteProjectResult struct. -type DeleteProjectResult struct { - DeleteProject string `json:"deleteProject"` -} - -// Projects struct. -type Projects struct { - Projects []Project //`json:"allProjects"` -} - -// Project struct. -type Project struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - GitURL string `json:"gitUrl,omitempty"` - PrivateKey string `json:"privateKey,omitempty"` - PublicKey string `json:"publicKey,omitempty"` - Subfolder string `json:"subfolder,omitempty"` - RouterPattern string `json:"routerPattern,omitempty"` - Branches string `json:"branches,omitempty"` - Pullrequests string `json:"pullrequests,omitempty"` - ProductionEnvironment string `json:"productionEnvironment,omitempty"` - StandbyProductionEnvironment string `json:"standbyProductionEnvironment,omitempty"` - AutoIdle *int `json:"autoIdle,omitempty"` - StorageCalc *int `json:"storageCalc,omitempty"` - OpenshiftProjectPattern string `json:"openshiftProjectPattern,omitempty"` - DevelopmentEnvironmentsLimit int `json:"developmentEnvironmentsLimit,omitempty"` - Created string `json:"created,omitempty"` - Openshift Openshift `json:"openshift,omitempty"` - EnvVariables []EnvironmentVariable `json:"envVariables,omitempty"` - Environments []Environment `json:"environments,omitempty"` - Deployments []Deployment `json:"deployments,omitempty"` - Notifications []interface{} `json:"notifications,omitempty"` - FactsUI *int `json:"factsUi,omitempty"` - ProblemsUI *int `json:"problemsUi,omitempty"` -} - -// ProjectPatch struct. -type ProjectPatch struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - GitURL string `json:"gitUrl,omitempty"` - PrivateKey string `json:"privateKey,omitempty"` - Subfolder string `json:"subfolder,omitempty"` - RouterPattern string `json:"routerPattern,omitempty"` - Branches string `json:"branches,omitempty"` - Pullrequests string `json:"pullrequests,omitempty"` - ProductionEnvironment string `json:"productionEnvironment,omitempty"` - StandbyProductionEnvironment string `json:"standbyProductionEnvironment,omitempty"` - AutoIdle *int `json:"autoIdle,omitempty"` - StorageCalc *int `json:"storageCalc,omitempty"` - OpenshiftProjectPattern string `json:"openshiftProjectPattern,omitempty"` - DevelopmentEnvironmentsLimit *int `json:"developmentEnvironmentsLimit,omitempty"` - Openshift *int `json:"openshift,omitempty"` - FactsUI *int `json:"factsUi,omitempty"` - ProblemsUI *int `json:"problemsUi,omitempty"` - DeploymentsDisabled *int `json:"deploymentsDisabled,omitempty"` -} - -// AddSSHKey . -type AddSSHKey struct { - ID string `json:"id,omitempty"` - Name string `json:"name"` - KeyValue string `json:"keyValue"` - KeyType SSHKeyType `json:"keyType"` - User User `json:"user"` -} - -// DeleteSSHKey . -type DeleteSSHKey struct { - Name string `json:"name"` -} - -// EnvironmentByName struct. -type EnvironmentByName struct { - Name string `json:"name"` - Project int `json:"project"` -} - -// AddOrUpdateEnvironmentStorage struct. -type AddOrUpdateEnvironmentStorage struct { - Environment int `json:"environment"` - PersistentStorageClaim string `json:"persistentStorageClaim"` - BytesUsed int `json:"bytesUsed"` -} - -// AddBackup struct. -type AddBackup struct { - ID int `json:"id,omitempty"` - Environment string `json:"environment"` - Source string `json:"source"` - BackupID string `json:"backupId"` - Created string `json:"created"` -} - -// DeleteBackup struct. -type DeleteBackup struct { - BackupID string `json:"backupId"` -} - -// AddRestore struct. -type AddRestore struct { - ID int `json:"id,omitempty"` - Status RestoreStatusType `json:"status"` - RestoreLocation string `json:"restoreLocation"` - Created string `json:"created"` - Execute bool `json:"execute"` - BackupID string `json:"backupId,omitempty"` -} - -// UpdateRestore struct. -type UpdateRestore struct { - BackupID string `json:"backupId"` - Patch UpdateRestorePatch `json:"patch"` -} - -// UpdateRestorePatch struct. -type UpdateRestorePatch struct { - Status string `json:"status,omitempty"` - Created string `json:"created,omitempty"` - RestoreLocation string `json:"restoreLocation,omitempty"` -} - -// Deployment struct. -type Deployment struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Status DeploymentStatusType `json:"status,omitempty"` - Created string `json:"created,omitempty"` - Started string `json:"started,omitempty"` - Completed string `json:"completed,omitempty"` - Environment int `json:"environment,omitempty"` - RemoteID string `json:"remoteId,omitempty"` - BuildLog string `json:"buildLog,omitempty"` -} - -// DeploymentEnv struct. -type DeploymentEnv struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Status DeploymentStatusType `json:"status,omitempty"` - Created string `json:"created,omitempty"` - Started string `json:"started,omitempty"` - Completed string `json:"completed,omitempty"` - Environment Environment `json:"environment,omitempty"` - RemoteID string `json:"remoteId,omitempty"` - BuildLog string `json:"buildLog,omitempty"` -} - -// DeleteDeployment struct. -type DeleteDeployment struct { - ID int `json:"id"` -} - -// UpdateDeployment struct. -type UpdateDeployment struct { - ID int `json:"id"` - Patch Deployment `json:"patch"` -} - -// Task struct. -type Task struct { - ID int `json:"id"` - Name string `json:"name"` - Status TaskStatusType `json:"status,omitempty"` - Created string `json:"created,omitempty"` - Started string `json:"started,omitempty"` - Completed string `json:"completed,omitempty"` - Environment int `json:"environment"` - Service string `json:"service,omitempty"` - Command string `json:"command,omitempty"` - RemoteID string `json:"remoteId,omitempty"` - Execute bool `json:"execute,omitempty"` -} - -// DeleteTask struct. -type DeleteTask struct { - ID int `json:"id"` -} - -// UpdateTask struct. -type UpdateTask struct { - ID int `json:"id"` - Patch Task `json:"patch"` -} - -// DeleteOpenshift struct. -type DeleteOpenshift struct { - Name string `json:"name"` -} - -// AddNotificationRocketChat struct. -type AddNotificationRocketChat struct { - Name string `json:"name"` - Webhook string `json:"webhook"` - Channel string `json:"channel"` -} - -// AddNotificationSlack struct. -type AddNotificationSlack struct { - Name string `json:"name"` - Webhook string `json:"webhook"` - Channel string `json:"channel"` -} - -// DeleteNotificationRocketChat struct. -type DeleteNotificationRocketChat struct { - Name string `json:"name"` -} - -// DeleteNotificationSlack struct. -type DeleteNotificationSlack struct { - Name string `json:"name"` -} - -// AddNotificationToProject struct. -type AddNotificationToProject struct { - Project string `json:"project"` - NotificationType NotificationType `json:"notificationType"` - NotificationName string `json:"notificationName"` -} - -// RemoveNotificationFromProject struct. -type RemoveNotificationFromProject struct { - Project string `json:"project"` - NotificationType NotificationType `json:"notificationType"` - NotificationName string `json:"notificationName"` -} - -// UpdateUser struct. -type UpdateUser struct { - User User `json:"user"` - Patch User `json:"patch"` -} - -// DeleteUser struct. -type DeleteUser struct { - User User `json:"user"` -} - -// DeleteProject struct. -type DeleteProject struct { - Project string `json:"project"` -} - -// UpdateOpenshift struct. -type UpdateOpenshift struct { - ID int `json:"id"` - Patch Openshift `json:"patch"` -} - -// UpdateNotificationRocketChatPatch struct. -type UpdateNotificationRocketChatPatch struct { - Name string `json:"name,omitempty"` - Webhook string `json:"webhook,omitempty"` - Channel string `json:"channel,omitempty"` -} - -// UpdateNotificationSlackPatch struct. -type UpdateNotificationSlackPatch struct { - Name string `json:"name,omitempty"` - Webhook string `json:"webhook,omitempty"` - Channel string `json:"channel,omitempty"` -} - -// UpdateNotificationSlack struct. -type UpdateNotificationSlack struct { - ID int `json:"id"` - Patch UpdateNotificationSlackPatch `json:"patch"` -} - -// UpdateNotificationRocketChatInput struct. -type UpdateNotificationRocketChatInput struct { - ID int `json:"id"` - Patch UpdateNotificationRocketChatPatch `json:"patch"` -} - -// UpdateSSHKeyPatch struct. -type UpdateSSHKeyPatch struct { - Name string `json:"name,omitempty"` - KeyValue string `json:"keyValue,omitempty"` - KeyType SSHKeyType `json:"keyType,omitempty"` -} - -// UpdateSSHKey struct. -type UpdateSSHKey struct { - ID int `json:"id"` - Patch UpdateSSHKeyPatch `json:"patch"` -} - -// UpdateEnvironment struct. -type UpdateEnvironment struct { - ID int `json:"id"` - Patch Environment `json:"patch"` -} - -// AddUpdateEnvironment struct. -type AddUpdateEnvironment struct { - Name string `json:"name"` - Patch Environment `json:"patch"` -} - -// DeleteEnvironment struct. -type DeleteEnvironment struct { - Name string `json:"name"` - Project string `json:"project"` - Execute bool `json:"execute"` -} - -// EnvVariable struct. -type EnvVariable struct { - ID int `json:"id,omitempty"` - Type EnvVariableType `json:"type,omitempty"` - TypeID int `json:"typeId"` - Name string `json:"name"` - Scope EnvVariableScope `json:"scope"` - Value string `json:"value"` -} - -// DeleteEnvVariable struct. -type DeleteEnvVariable struct { - ID int `json:"id"` -} - -// SetEnvironmentServices struct. -type SetEnvironmentServices struct { - Environment int `json:"environment"` - Services []string `json:"services"` -} - -// UploadFilesForTask struct. -type UploadFilesForTask struct { - Task int `json:"task"` - // @TODO - // Files []Upload `json:"files"` -} - -// DeleteFilesForTask struct. -type DeleteFilesForTask struct { - ID int `json:"id"` -} - -// DeployEnvironmentLatest struct. -type DeployEnvironmentLatest struct { - Environment Environment `json:"environment"` -} - -// DeployEnvironmentBranch struct. -type DeployEnvironmentBranch struct { - Project Project `json:"project"` - BranchName string `json:"branchName"` - BranchRef string `json:"branchRef,omitempty"` -} - -// DeployEnvironmentPullrequest struct. -type DeployEnvironmentPullrequest struct { - Project Project `json:"project"` - Number int `json:"number"` - Title string `json:"title"` - BaseBranchName string `json:"baseBranchName"` - BaseBranchRef string `json:"baseBranchRef"` - HeadBranchName string `json:"headBranchName"` - HeadBranchRef string `json:"headBranchRef"` -} - -// DeployEnvironmentPromote struct. -type DeployEnvironmentPromote struct { - SourceEnvironment Environment `json:"sourceEnvironment"` - Project Project `json:"project"` - DestinationEnvironment string `json:"destinationEnvironment"` -} - -// AddGroup struct. -type AddGroup struct { - Name string `json:"name"` - ParentGroup Group `json:"parentGroup,omitempty"` -} - -// AddUserToGroup struct. -type AddUserToGroup struct { - User User `json:"user"` - Group string `json:"group"` - Role GroupRole `json:"role"` -} - -// ProjectToGroup struct. -type ProjectToGroup struct { - Project string `json:"project"` - Group string `json:"group"` -} - -// UpdateGroup struct. -type UpdateGroup struct { - Group Group `json:"group"` - Patch Group `json:"patch"` -} - -// DeleteGroup struct. -type DeleteGroup struct { - Group Group `json:"group"` -} - -// UserGroup struct. -type UserGroup struct { - User User `json:"user"` - Group Group `json:"group"` -} - -// UserGroupRole struct. -type UserGroupRole struct { - User User `json:"user"` - Group Group `json:"group"` - Role GroupRole `json:"role"` -} - -// ProjectGroups struct. -type ProjectGroups struct { - Project Project `json:"project"` - Groups []Group `json:"groups"` -} - -// Environment struct. -type Environment struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - DeployType DeployType `json:"deployType,omitempty"` - DeployTitle string `json:"deployTitle,omitempty"` - DeployBaseRef string `json:"deployBaseRef,omitempty"` - DeployHeadRef string `json:"deployHeadRef,omitempty"` - AutoIdle *int `json:"autoIdle,omitempty"` - EnvironmentType EnvType `json:"environmentType,omitempty"` - OpenshiftProjectName string `json:"openshiftProjectName,omitempty"` - Created string `json:"created,omitempty"` - Deleted string `json:"deleted,omitempty"` - Route string `json:"route,omitempty"` - Routes string `json:"routes,omitempty"` - EnvVariables []EnvironmentVariable `json:"envVariables,omitempty"` - Backups []Backup `json:"backups,omitempty"` - Tasks []Task `json:"tasks,omitempty"` - Project int `json:"project,omitempty"` - AdvancedTasks []AdvancedTask `json:"advancedTasks"` -} - -// EnvironmentBackups struct. -type EnvironmentBackups struct { - OpenshiftProjectName string `json:"openshiftProjectName"` -} - -// Data . -type Data struct { - Data interface{} - Error interface{} -} - -// EnvironmentVariable struct. -type EnvironmentVariable struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Scope string `json:"scope,omitempty"` - Value string `json:"value,omitempty"` -} - -// AdvancedTask task def struct -type AdvancedTask struct { - ID int `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Description string `json:"description"` -} - -// Backup struct. -type Backup struct { - ID int `json:"id,omitempty"` - Source string `json:"source,omitempty"` - BackupID string `json:"backupId,omitempty"` - Created string `json:"created,omitempty"` - Deleted string `json:"deleted,omitempty"` - Environment int `json:"environment,omitempty"` - Restore Restore `json:"restore,omitempty"` -} - -// Restore struct. -type Restore struct { - ID int `json:"id,omitempty"` - BackupID string `json:"backupId,omitempty"` - Status string `json:"status,omitempty"` - RestoreLocation string `json:"restoreLocation,omitempty"` - Created string `json:"created,omitempty"` -} - -// RocketChats struct. -type RocketChats struct { - RocketChats []NotificationRocketChat `json:"rocketchats"` -} - -// Slacks struct. -type Slacks struct { - Slacks []NotificationSlack `json:"slacks"` -} diff --git a/pkg/api/users.go b/pkg/api/users.go deleted file mode 100644 index 0e52e6fb..00000000 --- a/pkg/api/users.go +++ /dev/null @@ -1,217 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - - "github.com/machinebox/graphql" -) - -// AddUser . -func (api *Interface) AddUser(user User) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($email: String!, $firstName: String, $lastName: String, $comment: String, $gitlabId: Int) { - addUser(input: { - email: $email - firstName: $firstName - lastName: $lastName - comment: $comment - gitlabId: $gitlabId - }) { - ...User - } - }` + userFragment) - req.Var("email", user.Email) - req.Var("firstName", user.FirstName) - req.Var("lastName", user.LastName) - req.Var("comment", user.Comment) - req.Var("gitlabId", user.GitlabID) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addUser"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// UpdateUser . -func (api *Interface) UpdateUser(user UpdateUser) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($email: String!, $patch: UpdateUserPatchInput!) { - updateUser(input: { - user: { - email: $email - } - patch: $patch - }) { - ...User - } - }` + userFragment) - req.Var("email", user.User.Email) - req.Var("patch", user.Patch) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["updateUser"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteUser . -func (api *Interface) DeleteUser(user User) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($email: String!) { - deleteUser(input: { - user: { - email: $email - } - }) - }`) - req.Var("email", user.Email) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteUser"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// GetUserBySSHKey . -func (api *Interface) GetUserBySSHKey(sshKey SSHKeyValue) ([]byte, error) { - req := graphql.NewRequest(` - query userBySshKey($sshKey: String!) { - userBySshKey(sshKey: $sshKey) { - ...User - } - }` + userFragment) - req.Var("sshKey", sshKey) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["userBySshKey"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// AddSSHKey . -func (api *Interface) AddSSHKey(sshKey AddSSHKey) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($id: Int, $name: String!, $keyValue: String!, $keyType: SshKeyType!, $userEmail: String!) { - addSshKey(input: { - id: $id - name: $name - keyValue: $keyValue - keyType: $keyType - user: { - email: $userEmail - } - }) { - ...SshKey - } - }` + sshKeyFragment) - req.Var("name", sshKey.Name) - req.Var("keyValue", sshKey.KeyValue) - req.Var("keyType", sshKey.KeyType) - req.Var("userEmail", sshKey.User.Email) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["addSshKey"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} - -// DeleteSSHKey . -func (api *Interface) DeleteSSHKey(sshKey DeleteSSHKey) ([]byte, error) { - req := graphql.NewRequest(` - mutation ($name: String!) { - deleteSshKey(input: { - name: $name - }) - }`) - req.Var("name", sshKey.Name) - if api.debug { - debugRequest(req) - } - returnType, err := api.RunQuery(req, Data{}) - if err != nil { - return []byte(""), err - } - reMappedResult := returnType.(map[string]interface{}) - jsonBytes, err := json.Marshal(reMappedResult["deleteSshKey"]) - if err != nil { - return []byte(""), err - } - if api.debug { - debugResponse(jsonBytes) - } - if string(jsonBytes) == "null" { - return []byte(""), errors.New("GraphQL API returned a null response, the requested resource may not exist, or there was an error. Use `--debug` to check what was returned") - } - return jsonBytes, nil -} diff --git a/pkg/graphql/main.go b/pkg/graphql/main.go deleted file mode 100644 index b091b559..00000000 --- a/pkg/graphql/main.go +++ /dev/null @@ -1,266 +0,0 @@ -package graphql - -import ( - "github.com/golang-jwt/jwt" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/pkg/api" -) - -// LagoonAPI . -func LagoonAPI(lc *lagoon.Config, debug bool) (api.Client, error) { - lagoon := lc.Current - lagoonAPI, err := api.NewWithToken( - lc.Lagoons[lagoon].Token, - lc.Lagoons[lagoon].GraphQL, - ) - lagoonAPI.Debug(debug) - if err != nil { - return nil, err - } - return lagoonAPI, nil -} - -func hasValidToken(lc *lagoon.Config, lagoon string) bool { - return lc.Lagoons[lagoon].Token != "" -} - -// VerifyTokenExpiry verfies if the current token is valid or not -func VerifyTokenExpiry(lc *lagoon.Config, lagoon string) bool { - var p jwt.Parser - token, _, err := p.ParseUnverified( - lc.Lagoons[lagoon].Token, &jwt.StandardClaims{}) - if err != nil { - return false - } - if token.Claims.Valid() != nil { - return false - } - return true -} - -// DefaultFragment is blank to use what is defined in api -var DefaultFragment = "" - -// ProjectByNameFragment . -var ProjectByNameFragment = `fragment Project on Project { - id - name - gitUrl - subfolder - routerPattern - branches - pullrequests - problemsUi - factsUi - productionEnvironment - deployTargetConfigs{ - id - deployTarget{ - id - name - token - } - - } - environments { - id - name - openshiftProjectName - environmentType - deployType - route - } - autoIdle - storageCalc - developmentEnvironmentsLimit -}` - -// ProjectByNameMinimalFragment . -var ProjectByNameMinimalFragment = `fragment Project on Project { - id - name -}` - -// ProjectAndEnvironmentEnvVars . -var ProjectAndEnvironmentEnvVars = `fragment Project on Project { - id - name - envVariables { - id - name - scope - } - environments { - openshiftProjectName - name - envVariables { - id - name - scope - } - } -}` - -// ProjectEnvironmentEnvVars . -var ProjectEnvironmentEnvVars = `fragment Project on Project { - id - name - environments { - openshiftProjectName - name - envVariables { - id - name - scope - } - } -}` - -// ProjectEnvironmentEnvVarsRevealed . -var ProjectEnvironmentEnvVarsRevealed = `fragment Project on Project { - id - name - environments { - openshiftProjectName - name - envVariables { - id - name - scope - value - } - } -}` - -// ProjectAndEnvironmentEnvVarsRevealed . -var ProjectAndEnvironmentEnvVarsRevealed = `fragment Project on Project { - id - name - envVariables { - id - name - scope - value - } - environments { - openshiftProjectName - name - envVariables { - id - name - scope - value - } - } -}` - -// ProjectEnvVars . -var ProjectEnvVars = `fragment Project on Project { - id - name - envVariables { - id - name - scope - } -}` - -// ProjectEnvVarsRevealed . -var ProjectEnvVarsRevealed = `fragment Project on Project { - id - name - envVariables { - id - name - scope - value - } -}` - -// AllProjectsFragment . -var AllProjectsFragment = `fragment Project on Project { - id - gitUrl - name, - developmentEnvironmentsLimit, - productionEnvironment, - environments { - environmentType, - route - } -}` - -// RocketChatFragment . -var RocketChatFragment = `fragment Notification on NotificationRocketChat { - id - name - webhook - channel -}` - -// SlackFragment . -var SlackFragment = `fragment Notification on NotificationSlack { - id - name - webhook - channel -}` - -// EnvironmentVariablesFragment . -var EnvironmentVariablesFragment = `fragment Environment on Environment { - id - name - environmentType - openshiftProjectName - envVariables { - id - name - } -}` - -// EnvironmentEnvVars . -var EnvironmentEnvVars = `fragment Environment on Environment { - id - name - envVariables { - id - name - scope - } -}` - -// EnvironmentEnvVarsRevealed . -var EnvironmentEnvVarsRevealed = `fragment Environment on Environment { - id - name - envVariables { - id - name - scope - value - } -}` - -// ProjectNameID . -var ProjectNameID = `fragment Project on Project { - id - name -}` - -// EnvironmentByNameFragment . -var EnvironmentByNameFragment = `fragment Environment on Environment { - id - name - route - routes - deployType - environmentType - openshiftProjectName - updated - created - deleted - deployTitle - deployBaseRef - deployHeadRef - autoIdle -}` diff --git a/pkg/graphql/main_test.go b/pkg/graphql/main_test.go deleted file mode 100644 index a1505738..00000000 --- a/pkg/graphql/main_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package graphql - -import ( - "testing" - - "github.com/uselagoon/lagoon-cli/internal/lagoon" -) - -func TestValidateToken(t *testing.T) { - lc := lagoon.Config{ - Lagoons: map[string]lagoon.Context{}, - } - got := hasValidToken(&lc, "test") - if got == true { - t.Error("HasValidToken should fail as no token is set by default", got) - } - // set the context with a valid token - lc.Lagoons["test"] = lagoon.Context{ - Token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NzI3Nzk5MjYsImV4cCI6NDc1OTk4OTUzMSwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.9XKxJps00mGzgneaEp0nmI8aXlolMrD-Do2IooTP7d0", - } - got = hasValidToken(&lc, "test") - if got == false { - t.Error("HasValidToken should not fail once a token is set", got) - } - got = VerifyTokenExpiry(&lc, "test") - if got == false { - t.Error("ValidateToken should not fail if the token is valid", got) - } - // set the context with an expired token - lc.Lagoons["test"] = lagoon.Context{ - Token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NDEyNDM0MTMsImV4cCI6MTU0MTI0NDYxNCwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.2wkAPeyVHAhGps_OEe_a8RXmv7_9GwP4ttFsjrLPZ84", - } - got = VerifyTokenExpiry(&lc, "test") - if got == true { - t.Error("ValidateToken should fail if the token is invalid or expired", got) - } -} diff --git a/pkg/lagoon/environments/deployments.go b/pkg/lagoon/environments/deployments.go deleted file mode 100644 index 51baa047..00000000 --- a/pkg/lagoon/environments/deployments.go +++ /dev/null @@ -1,115 +0,0 @@ -package environments - -import ( - "encoding/json" - "errors" - "strconv" - "strings" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// GetEnvironmentDeployments . -func (e *Environments) GetEnvironmentDeployments(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectNameID) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - customRequest := api.CustomRequest{ - Query: `query ($project: Int!, $name: String!){ - environmentByName( - project: $project - name: $name - ){ - deployments{ - name - id - remoteId - status - created - started - completed - } - } - }`, - Variables: map[string]interface{}{ - "name": environmentName, - "project": projectInfo.ID, - }, - MappedResult: "environmentByName", - } - environmentByName, err := e.api.Request(customRequest) - if err != nil { - return []byte(""), err - } - returnResult, err := processEnvironmentDeployments(environmentByName) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processEnvironmentDeployments(environmentByName []byte) ([]byte, error) { - var projects api.Project - err := json.Unmarshal([]byte(environmentByName), &projects) - if err != nil { - return []byte(""), errors.New(noDataError) // @TODO could be a permissions thing when no data is returned - } - // process the data for output - data := []output.Data{} - for _, deployment := range projects.Deployments { - deploymentID := returnNonEmptyString(strconv.Itoa(deployment.ID)) - remoteID := returnNonEmptyString(deployment.RemoteID) - deploymentName := returnNonEmptyString(strings.Replace(deployment.Name, " ", "_", -1)) //remove spaces to make friendly for parsing with awk - deploymentStatus := returnNonEmptyString(string(deployment.Status)) - deploymentCreated := returnNonEmptyString(string(deployment.Created)) - deploymentStarted := returnNonEmptyString(string(deployment.Started)) - deploymentComplete := returnNonEmptyString(string(deployment.Completed)) - data = append(data, []string{ - deploymentID, - remoteID, - deploymentName, - deploymentStatus, - deploymentCreated, - deploymentStarted, - deploymentComplete, - }) - } - dataMain := output.Table{ - Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed"}, - Data: data, - } - return json.Marshal(dataMain) -} - -// GetDeploymentLog . -func (e *Environments) GetDeploymentLog(deploymentID string) ([]byte, error) { - customRequest := api.CustomRequest{ - Query: `query ($id: String!){ - deploymentByRemoteId( - id: $id - ){ - id - buildLog - } - }`, - Variables: map[string]interface{}{ - "id": deploymentID, - }, - MappedResult: "deploymentByRemoteId", - } - deploymentByRemoteID, err := e.api.Request(customRequest) - return deploymentByRemoteID, err -} diff --git a/pkg/lagoon/environments/deployments_test.go b/pkg/lagoon/environments/deployments_test.go deleted file mode 100644 index 2c51e78c..00000000 --- a/pkg/lagoon/environments/deployments_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package environments - -import ( - "testing" -) - -func TestGetEnvironmentDeployments(t *testing.T) { - var testData = `{ - "deployments":[ - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":14,"name":"build-2","remoteId":null,"started":"2018-10-07 23:03:41","status":"failed"}, - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":1,"name":"build-1","remoteId":null,"started":"2018-10-07 23:03:41","status":"complete"}, - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":4,"name":"build-1","remoteId":null,"started":"2018-10-07 23:03:41","status":"complete"}, - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":5,"name":"build-2","remoteId":null,"started":"2018-10-07 23:03:41","status":"failed"}, - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":7,"name":"build-1","remoteId":null,"started":"2018-10-07 23:03:41","status":"complete"}, - {"completed":"2018-10-07 23:20:41","created":"2018-10-07 23:02:41","id":8,"name":"build-2","remoteId":null,"started":"2018-10-07 23:03:41","status":"failed"} - ] - }` - var testSuccess = `{"header":["ID","RemoteID","Name","Status","Created","Started","Completed"],"data":[["14","-","build-2","failed","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"],["1","-","build-1","complete","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"],["4","-","build-1","complete","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"],["5","-","build-2","failed","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"],["7","-","build-1","complete","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"],["8","-","build-2","failed","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:20:41"]]}` - - testResult, err := processEnvironmentDeployments([]byte(testData)) - if err != nil { - t.Error("Should not fail if processing succeeded, error was:", err) - } - if string(testResult) != testSuccess { - checkEqual(t, string(testResult), testSuccess, "projectInfo processing failed") - } -} diff --git a/pkg/lagoon/environments/main.go b/pkg/lagoon/environments/main.go deleted file mode 100644 index 1be98d34..00000000 --- a/pkg/lagoon/environments/main.go +++ /dev/null @@ -1,204 +0,0 @@ -package environments - -import ( - "encoding/json" - "fmt" - "strconv" - - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// Environments . -type Environments struct { - debug bool - api api.Client -} - -// Client . -type Client interface { - DeployEnvironmentBranch(string, string) ([]byte, error) - DeleteEnvironment(string, string) ([]byte, error) - GetDeploymentLog(string) ([]byte, error) - GetEnvironmentInfo(string, string) ([]byte, error) - ListEnvironmentVariables(string, string, bool) ([]byte, error) - GetEnvironmentDeployments(string, string) ([]byte, error) - GetEnvironmentTasks(string, string) ([]byte, error) - RunDrushArchiveDump(string, string) ([]byte, error) - RunDrushSQLDump(string, string) ([]byte, error) - RunDrushCacheClear(string, string) ([]byte, error) - RunCustomTask(string, string, api.Task) ([]byte, error) - AddEnvironmentVariableToEnvironment(string, string, api.EnvVariable) ([]byte, error) - DeleteEnvironmentVariableFromEnvironment(string, string, api.EnvVariable) ([]byte, error) - PromoteEnvironment(string, string, string) ([]byte, error) - InvokeAdvancedTaskDefinition(string, string, string) ([]byte, error) - ListInvokableAdvancedTaskDefinitions(string, string) ([]byte, error) -} - -// New . -func New(lc *lagoon.Config, debug bool) (Client, error) { - lagoonAPI, err := graphql.LagoonAPI(lc, debug) - if err != nil { - return &Environments{}, err - } - return &Environments{ - debug: debug, - api: lagoonAPI, - }, nil - -} - -var noDataError = "no data returned from the lagoon api" - -// DeployEnvironmentBranch . -func (e *Environments) DeployEnvironmentBranch(projectName string, branchName string) ([]byte, error) { - customRequest := api.CustomRequest{ - Query: `mutation ($project: String!, $branch: String!){ - deployEnvironmentBranch( - input: { - project:{name: $project} - branchName: $branch - } - ) - }`, - Variables: map[string]interface{}{ - "project": projectName, - "branch": branchName, - }, - MappedResult: "deployEnvironmentBranch", - } - returnResult, err := e.api.Request(customRequest) - return returnResult, err -} - -// DeleteEnvironment . -func (e *Environments) DeleteEnvironment(projectName string, environmentName string) ([]byte, error) { - evironment := api.DeleteEnvironment{ - Name: environmentName, - Project: projectName, - Execute: true, - } - returnResult, err := e.api.DeleteEnvironment(evironment) - return returnResult, err -} - -// GetEnvironmentInfo will get basic info about a project -func (e *Environments) GetEnvironmentInfo(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, graphql.EnvironmentByNameFragment) - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - returnResult, err := processEnvInfo(environmentByName) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processEnvInfo(projectByName []byte) ([]byte, error) { - var environment api.Environment - err := json.Unmarshal([]byte(projectByName), &environment) - if err != nil { - return []byte(""), err - } - environmentData := processEnvExtra(environment) - var data []output.Data - data = append(data, environmentData) - dataMain := output.Table{ - Header: []string{"ID", "EnvironmentName", "EnvironmentType", "DeployType", "Created", "OpenshiftProjectName", "Route", "Routes", "AutoIdle", "DeployTitle", "DeployBaseRef", "DeployHeadRef"}, - Data: data, - } - return json.Marshal(dataMain) -} - -func processEnvExtra(environment api.Environment) []string { - envID := returnNonEmptyString(strconv.Itoa(environment.ID)) - envName := returnNonEmptyString(string(environment.Name)) - envEnvironmentType := returnNonEmptyString(string(environment.EnvironmentType)) - envDeployType := returnNonEmptyString(string(environment.DeployType)) - envCreated := returnNonEmptyString(string(environment.Created)) - envOpenshiftProjectName := returnNonEmptyString(string(environment.OpenshiftProjectName)) - envRoute := returnNonEmptyString(string(environment.Route)) - envRoutes := returnNonEmptyString(string(environment.Routes)) - envDeployTitle := returnNonEmptyString(string(environment.DeployTitle)) - envDeployBaseRef := returnNonEmptyString(string(environment.DeployBaseRef)) - envDeployHeadRef := returnNonEmptyString(string(environment.DeployHeadRef)) - envAutoIdle := *environment.AutoIdle - data := []string{ - fmt.Sprintf("%v", envID), - fmt.Sprintf("%v", envName), - fmt.Sprintf("%v", envEnvironmentType), - fmt.Sprintf("%v", envDeployType), - fmt.Sprintf("%v", envCreated), - fmt.Sprintf("%v", envOpenshiftProjectName), - fmt.Sprintf("%v", envRoute), - fmt.Sprintf("%v", envRoutes), - fmt.Sprintf("%v", envAutoIdle), - fmt.Sprintf("%v", envDeployTitle), - fmt.Sprintf("%v", envDeployBaseRef), - fmt.Sprintf("%v", envDeployHeadRef), - } - return data -} - -func returnNonEmptyString(value string) string { - if len(value) == 0 { - value = "-" - } - return value -} - -// PromoteEnvironment . -func (e *Environments) PromoteEnvironment(projectName string, sourceEnv string, destEnv string) ([]byte, error) { - customRequest := api.CustomRequest{ - Query: `mutation deployEnvironmentPromote ($project: String!, $sourceEnv: String!, $destEnv: String!){ - deployEnvironmentPromote(input:{ - sourceEnvironment:{ - name: $sourceEnv - project:{ - name: $project - } - } - project:{ - name: $project - } - destinationEnvironment: $destEnv - }) - }`, - Variables: map[string]interface{}{ - "project": projectName, - "sourceEnv": sourceEnv, - "destEnv": destEnv, - }, - MappedResult: "deployEnvironmentPromote", - } - returnResult, err := e.api.Request(customRequest) - return returnResult, err -} diff --git a/pkg/lagoon/environments/main_test.go b/pkg/lagoon/environments/main_test.go deleted file mode 100644 index c3f3f035..00000000 --- a/pkg/lagoon/environments/main_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package environments - -import ( - "bytes" - "reflect" - "testing" -) - -func checkEqual(t *testing.T, got, want interface{}, msgs ...interface{}) { - if !reflect.DeepEqual(got, want) { - buf := bytes.Buffer{} - buf.WriteString("got:\n[%v]\nwant:\n[%v]\n") - for _, v := range msgs { - buf.WriteString(v.(string)) - } - t.Errorf(buf.String(), got, want) - } -} - -func TestGetEnvironmentByName(t *testing.T) { - var all = `{"autoIdle":1,"created":"2019-10-29 04:26:11","deleted":"0000-00-00 00:00:00","deployBaseRef":"Master","deployHeadRef":null,"deployTitle":null,"deployType":"branch","environmentType":"production","id":3,"name":"Master","openshiftProjectName":"high-cotton-master","route":"http://highcotton.org","routes":"http://highcotton.org,https://varnish-highcotton-org-prod.us.amazee.io,https://nginx-highcotton-org-prod.us.amazee.io","updated":"2019-10-29 04:26:43"}` - var allSuccess = `{"header":["ID","EnvironmentName","EnvironmentType","DeployType","Created","OpenshiftProjectName","Route","Routes","AutoIdle","DeployTitle","DeployBaseRef","DeployHeadRef"],"data":[["3","Master","production","branch","2019-10-29 04:26:11","high-cotton-master","http://highcotton.org","http://highcotton.org,https://varnish-highcotton-org-prod.us.amazee.io,https://nginx-highcotton-org-prod.us.amazee.io","1","-","Master","-"]]}` - - testResult, err := processEnvInfo([]byte(all)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "projectInfo processing failed") - } -} diff --git a/pkg/lagoon/environments/tasks.go b/pkg/lagoon/environments/tasks.go deleted file mode 100644 index 00811349..00000000 --- a/pkg/lagoon/environments/tasks.go +++ /dev/null @@ -1,440 +0,0 @@ -package environments - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// RunDrushArchiveDump will trigger a drush archive dump task -func (e *Environments) RunDrushArchiveDump(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, "") - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation runArdTask ($environment: Int!) { - taskDrushArchiveDump(environment: $environment) { - id - } - }`, - Variables: map[string]interface{}{ - "environment": environmentInfo.ID, - }, - MappedResult: "taskDrushArchiveDump", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// RunDrushSQLDump will trigger a drush archive dump task -func (e *Environments) RunDrushSQLDump(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, "") - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation runSqlDump ($environment: Int!) { - taskDrushSqlDump(environment: $environment) { - id - } - }`, - Variables: map[string]interface{}{ - "environment": environmentInfo.ID, - }, - MappedResult: "taskDrushSqlDump", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// RunDrushCacheClear will trigger a drush archive dump task -func (e *Environments) RunDrushCacheClear(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, "") - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation runCacheClear ($environment: Int!) { - taskDrushCacheClear(environment: $environment) { - id - } - }`, - Variables: map[string]interface{}{ - "environment": environmentInfo.ID, - }, - MappedResult: "taskDrushCacheClear", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// GetEnvironmentTasks . -func (e *Environments) GetEnvironmentTasks(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectNameID) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - customRequest := api.CustomRequest{ - Query: `query ($project: Int!, $name: String!){ - environmentByName( - project: $project - name: $name - ){ - tasks{ - name - id - remoteId - status - created - started - completed - } - } - }`, - Variables: map[string]interface{}{ - "name": environmentName, - "project": projectInfo.ID, - }, - MappedResult: "environmentByName", - } - environmentByName, err := e.api.Request(customRequest) - if err != nil { - return []byte(""), err - } - returnResult, err := processEnvironmentTasks(environmentByName) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processEnvironmentTasks(environmentByName []byte) ([]byte, error) { - var environment api.Environment - err := json.Unmarshal([]byte(environmentByName), &environment) - if err != nil { - return []byte(""), errors.New(noDataError) // @TODO could be a permissions thing when no data is returned - } - // process the data for output - data := []output.Data{} - for _, task := range environment.Tasks { - remoteID := returnNonEmptyString(task.RemoteID) - taskID := returnNonEmptyString(strconv.Itoa(task.ID)) - taskName := returnNonEmptyString(strings.Replace(task.Name, " ", "_", -1)) //remove spaces to make friendly for parsing with awk - taskStatus := returnNonEmptyString(string(task.Status)) - taskCreated := returnNonEmptyString(string(task.Created)) - taskStarted := returnNonEmptyString(string(task.Started)) - taskComplete := returnNonEmptyString(string(task.Completed)) - taskService := returnNonEmptyString(task.Service) - data = append(data, []string{ - taskID, - remoteID, - taskName, - taskStatus, - taskCreated, - taskStarted, - taskComplete, - taskService, - }) - } - dataMain := output.Table{ - Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed", "Service"}, - Data: data, - } - return json.Marshal(dataMain) -} - -// RunCustomTask will trigger a drush archive dump task -func (e *Environments) RunCustomTask(projectName string, environmentName string, task api.Task) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, "") - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation addTask ($environment: Int!, $name: String!, $command: String!, $service: String!) { - addTask(input:{ - environment: $environment - command: $command - execute:true - name: $name - service: $service - }) { - id - } - }`, - Variables: map[string]interface{}{ - "environment": environmentInfo.ID, - "name": task.Name, - "service": task.Service, - "command": task.Command, - }, - MappedResult: "addTask", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -const environmentWithTasksFragment = `fragment Environment on Environment { - id - name - route - routes - deployType - environmentType - openshiftProjectName - updated - created - deleted - advancedTasks { - ... on AdvancedTaskDefinitionCommand { - id - name - description - } - ... on AdvancedTaskDefinitionImage { - id - name - description - } - } -}` - -// ListInvokableAdvancedTaskDefinitions returns a list of tasks invokable against an environment -func (e *Environments) ListInvokableAdvancedTaskDefinitions(projectName string, environmentName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - - environmentByName, err := e.api.GetEnvironmentByName(environment, environmentWithTasksFragment) - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - retvar, _ := json.Marshal(environmentInfo.AdvancedTasks) - return retvar, nil -} - -// InvokeAdvancedTaskDefinition will attempt to invoke an advanced task definition on an environment -func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environmentName string, advancedTaskName string) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - - environmentByName, err := e.api.GetEnvironmentByName(environment, environmentWithTasksFragment) - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - var taskId int - for _, task := range environmentInfo.AdvancedTasks { - if advancedTaskName == task.Name { - taskId = task.ID - } - } - - if taskId == 0 { - return nil, fmt.Errorf(fmt.Sprintf("Could not find a task `%v` for project/environment %v/%v", - advancedTaskName, projectName, environmentName)) - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation invokeRegisteredTask ($environment: Int!, $advancedTaskDefinition: Int!) { - invokeRegisteredTask(advancedTaskDefinition: $advancedTaskDefinition, environment: $environment) { - id - name - status - } - }`, - Variables: map[string]interface{}{ - "advancedTaskDefinition": taskId, - "environment": environmentInfo.ID, - }, - MappedResult: "invokeRegisteredTask", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} diff --git a/pkg/lagoon/environments/tasks_test.go b/pkg/lagoon/environments/tasks_test.go deleted file mode 100644 index 0aadbefe..00000000 --- a/pkg/lagoon/environments/tasks_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package environments - -import ( - "testing" -) - -func TestListEnvironmentTassks(t *testing.T) { - var all = `{"tasks":[ - {"completed":null,"created":"2019-11-10 22:04:58","id":31,"name":"Drush cache-clear","remoteId":null,"started":null,"status":"failed"}, - {"completed":"2018-10-07 23:13:41","created":"2018-10-07 23:02:41","id":5,"name":"Drupal Archive","remoteId":null,"started":"2018-10-07 23:03:41","status":"succeeded"}, - {"completed":"2018-10-07 23:05:41","created":"2018-10-07 23:02:41","id":6,"name":"Drupal Archive","remoteId":null,"started":"2018-10-07 23:03:41","status":"failed"}, - {"completed":null,"created":"2018-10-07 23:02:41","id":7,"name":"Site Status","remoteId":null,"started":"2018-10-07 23:03:41","status":"active"}, - {"completed":null,"created":"2018-10-07 23:02:41","id":4,"name":"Site Status","remoteId":null,"started":"2018-10-07 23:03:41","status":"active"}, - {"completed":null,"created":"2018-10-07 23:02:41","id":16,"name":"Site Status","remoteId":"600abdae-003f-11ea-bcee-02d6ad974cf2","started":"2018-10-07 23:03:41","status":"active"} - ]}` - var allSuccess = `{"header":["ID","RemoteID","Name","Status","Created","Started","Completed","Service"],"data":[["31","-","Drush_cache-clear","failed","2019-11-10 22:04:58","-","-","-"],["5","-","Drupal_Archive","succeeded","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:13:41","-"],["6","-","Drupal_Archive","failed","2018-10-07 23:02:41","2018-10-07 23:03:41","2018-10-07 23:05:41","-"],["7","-","Site_Status","active","2018-10-07 23:02:41","2018-10-07 23:03:41","-","-"],["4","-","Site_Status","active","2018-10-07 23:02:41","2018-10-07 23:03:41","-","-"],["16","600abdae-003f-11ea-bcee-02d6ad974cf2","Site_Status","active","2018-10-07 23:02:41","2018-10-07 23:03:41","-","-"]]}` - - testResult, err := processEnvironmentTasks([]byte(all)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "projectInfo processing failed") - } -} diff --git a/pkg/lagoon/environments/variables.go b/pkg/lagoon/environments/variables.go deleted file mode 100644 index 6d7fc846..00000000 --- a/pkg/lagoon/environments/variables.go +++ /dev/null @@ -1,191 +0,0 @@ -package environments - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// AddEnvironmentVariableToEnvironment will list all environments for a project -func (e *Environments) AddEnvironmentVariableToEnvironment(projectName string, environmentName string, envVar api.EnvVariable) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, "") - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - customReq := api.CustomRequest{ - Query: `mutation addEnvironmentVariableToProject ($type: EnvVariableType!, $typeId: Int!, $scope: EnvVariableScope!, $name: String!, $value: String!) { - addEnvVariable(input:{type: $type, typeId: $typeId, scope: $scope, name: $name, value: $value}) { - id - } - }`, - Variables: map[string]interface{}{ - "type": api.EnvironmentVar, - "typeId": environmentInfo.ID, - "scope": envVar.Scope, - "name": envVar.Name, - "value": envVar.Value, - }, - MappedResult: "addEnvVariable", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// DeleteEnvironmentVariableFromEnvironment . -func (e *Environments) DeleteEnvironmentVariableFromEnvironment(projectName string, environmentName string, envVar api.EnvVariable) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectEnvironmentEnvVars) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - // get the environment info from lagoon, we need the environment ID for later - // we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - environmentByName, err := e.api.GetEnvironmentByName(environment, graphql.EnvironmentVariablesFragment) - if err != nil { - return []byte(""), err - } - - var envVars api.Environment - err = json.Unmarshal([]byte(environmentByName), &envVars) - if err != nil { - return []byte(""), err - } - for _, v := range envVars.EnvVariables { - if envVar.Name == v.Name { - envVar.ID = v.ID - break - } - } - if envVar.ID == 0 { - return []byte(""), errors.New("no matching var found") - } - // run the query to delete the environment variable to lagoon - // we consume the project ID here - customReq := api.CustomRequest{ - Query: `mutation deleteEnvironmentVariableFromProject ($id: Int!) { - deleteEnvVariable(input:{id: $id}) - }`, - Variables: map[string]interface{}{ - "id": envVar.ID, - }, - MappedResult: "deleteEnvVariable", - } - returnResult, err := e.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// ListEnvironmentVariables will list the environment variables for a project and all environments attached -func (e *Environments) ListEnvironmentVariables(projectName string, environmentName string, revealValue bool) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := e.api.GetProjectByName(project, graphql.ProjectByNameMinimalFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - // get the environment info from lagoon, we consume the project ID here - environment := api.EnvironmentByName{ - Name: environmentName, - Project: projectInfo.ID, - } - queryFragment := graphql.EnvironmentEnvVars - if revealValue { - queryFragment = graphql.EnvironmentEnvVarsRevealed - } - environmentByName, err := e.api.GetEnvironmentByName(environment, queryFragment) - if err != nil { - return []byte(""), err - } - var environmentInfo api.Environment - err = json.Unmarshal([]byte(environmentByName), &environmentInfo) - if err != nil { - return []byte(""), err - } - returnResult, err := processEnvironmentVariables(environmentInfo, projectName, revealValue) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processEnvironmentVariables(envVars api.Environment, projectName string, revealValue bool) ([]byte, error) { - data := []output.Data{} - if len(envVars.EnvVariables) != 0 { - for _, environmentEnvVar := range envVars.EnvVariables { - envVarRow := []string{ - fmt.Sprintf("%v", environmentEnvVar.ID), - projectName, - envVars.Name, - environmentEnvVar.Scope, - environmentEnvVar.Name, - } - if revealValue { - envVarRow = append(envVarRow, environmentEnvVar.Value) - } - data = append(data, envVarRow) - } - } - dataMain := output.Table{ - Header: []string{"ID", "Project", "Environment", "Scope", "VariableName"}, - Data: data, - } - if revealValue { - dataMain.Header = append(dataMain.Header, "VariableValue") - } - return json.Marshal(dataMain) -} diff --git a/pkg/lagoon/environments/variables_test.go b/pkg/lagoon/environments/variables_test.go deleted file mode 100644 index 6a786c75..00000000 --- a/pkg/lagoon/environments/variables_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package environments - -import ( - "encoding/json" - "testing" - - "github.com/uselagoon/lagoon-cli/pkg/api" -) - -func TestListEnvironmentVariables(t *testing.T) { - var all = `{ - "envVariables":[ - {"id":10,"name":"TEST_VAR10","value":"value10","scope":"runtime"}, - {"id":13,"name":"TEST_VAR20","value":"value20","scope":"build"}, - {"id":15,"name":"TEST_VAR30","value":"value30","scope":"build"}, - {"id":17,"name":"TEST_VAR50","value":"value50","scope":"build"} - ],"name":"master","openshiftProjectName":"high-cotton-master"}` - var allSuccess = `{"header":["ID","Project","Environment","Scope","VariableName"],"data":[["10","high-cotton","master","runtime","TEST_VAR10"],["13","high-cotton","master","build","TEST_VAR20"],["15","high-cotton","master","build","TEST_VAR30"],["17","high-cotton","master","build","TEST_VAR50"]]}` - var allSuccess2 = `{"header":["ID","Project","Environment","Scope","VariableName","VariableValue"],"data":[["10","high-cotton","master","runtime","TEST_VAR10","value10"],["13","high-cotton","master","build","TEST_VAR20","value20"],["15","high-cotton","master","build","TEST_VAR30","value30"],["17","high-cotton","master","build","TEST_VAR50","value50"]]}` - - env := api.Environment{} - json.Unmarshal([]byte(all), &env) - testResult, err := processEnvironmentVariables(env, "high-cotton", false) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "projectInfo processing failed") - } - testResult, err = processEnvironmentVariables(env, "high-cotton", true) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess2 { - checkEqual(t, string(testResult), allSuccess2, "projectInfo processing failed") - } -} diff --git a/pkg/lagoon/projects/main.go b/pkg/lagoon/projects/main.go deleted file mode 100644 index b6598638..00000000 --- a/pkg/lagoon/projects/main.go +++ /dev/null @@ -1,275 +0,0 @@ -package projects - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// Projects . -type Projects struct { - debug bool - api api.Client -} - -// Client . -type Client interface { - ListAllProjects() ([]byte, error) - ListProjectVariables(string, bool) ([]byte, error) - GetProjectKey(string, bool) ([]byte, error) - GetProjectInfo(string) ([]byte, error) - DeleteProject(string) ([]byte, error) - AddProject(string, string) ([]byte, error) - UpdateProject(string, string) ([]byte, error) - AddEnvironmentVariableToProject(string, api.EnvVariable) ([]byte, error) - DeleteEnvironmentVariableFromProject(string, api.EnvVariable) ([]byte, error) -} - -// New . -func New(lc *lagoon.Config, debug bool) (Client, error) { - lagoonAPI, err := graphql.LagoonAPI(lc, debug) - if err != nil { - return &Projects{}, err - } - return &Projects{ - debug: debug, - api: lagoonAPI, - }, nil - -} - -// ListAllProjects will list all projects -func (p *Projects) ListAllProjects() ([]byte, error) { - allProjects, err := p.api.GetAllProjects(graphql.AllProjectsFragment) - if err != nil { - return []byte(""), err - } - returnResult, err := processAllProjects(allProjects) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processAllProjects(allProjects []byte) ([]byte, error) { - var projects []api.Project - err := json.Unmarshal([]byte(allProjects), &projects) - if err != nil { - return []byte(""), err - } - // process the data for output - data := []output.Data{} - for _, project := range projects { - projectData := processProject(project) - data = append(data, projectData) - } - dataMain := output.Table{ - Header: []string{"ID", "ProjectName", "GitURL", "ProductionEnvironment", "DevEnvironments"}, - Data: data, - } - return json.Marshal(dataMain) -} - -func processProject(project api.Project) []string { - // count the current dev environments in a project - var currentDevEnvironments = 0 - for _, environment := range project.Environments { - if environment.EnvironmentType == "development" { - currentDevEnvironments++ - } - } - data := []string{ - fmt.Sprintf("%v", project.ID), - fmt.Sprintf("%v", project.Name), - fmt.Sprintf("%v", project.GitURL), - fmt.Sprintf("%v", project.ProductionEnvironment), - fmt.Sprintf("%v/%v", currentDevEnvironments, project.DevelopmentEnvironmentsLimit), - } - return data -} - -// GetProjectInfo will get basic info about a project -func (p *Projects) GetProjectInfo(projectName string) ([]byte, error) { - // get project info from lagoon - project := api.Project{ - Name: projectName, - } - projectByName, err := p.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - returnResult, err := processProjectInfo(projectByName) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processProjectInfo(projectByName []byte) ([]byte, error) { - var project api.Project - err := json.Unmarshal([]byte(projectByName), &project) - if err != nil { - return []byte(""), err - } - projectData := processProjectExtra(project) - var data []output.Data - data = append(data, projectData) - dataMain := output.Table{ - Header: []string{"ID", "ProjectName", "GitURL", "Branches", "PullRequests", "ProductionRoute", "DevEnvironments", "DevEnvLimit", "ProductionEnv", "RouterPattern", "AutoIdle", "FactsUI", "ProblemsUI"}, - Data: data, - } - return json.Marshal(dataMain) -} - -func processProjectExtra(project api.Project) []string { - // count the current dev environments in a project - var currentDevEnvironments = 0 - var projectRoute = "none" - for _, environment := range project.Environments { - if environment.EnvironmentType == "development" { - currentDevEnvironments++ - } - if environment.EnvironmentType == "production" { - projectRoute = environment.Route - } - } - data := []string{ - fmt.Sprintf("%v", project.ID), - fmt.Sprintf("%v", project.Name), - fmt.Sprintf("%v", project.GitURL), - fmt.Sprintf("%v", project.Branches), - fmt.Sprintf("%v", project.Pullrequests), - fmt.Sprintf("%v", projectRoute), - fmt.Sprintf("%v/%v", currentDevEnvironments, project.DevelopmentEnvironmentsLimit), - fmt.Sprintf("%v", project.DevelopmentEnvironmentsLimit), - fmt.Sprintf("%v", project.ProductionEnvironment), - project.RouterPattern, - fmt.Sprintf("%v", *project.AutoIdle), - fmt.Sprintf("%v", *project.FactsUI), - fmt.Sprintf("%v", *project.ProblemsUI), - } - return data -} - -// AddProject . -func (p *Projects) AddProject(projectName string, jsonPatch string) ([]byte, error) { - project := api.ProjectPatch{} - err := json.Unmarshal([]byte(jsonPatch), &project) - if err != nil { - return []byte(""), err - } - project.Name = projectName - projectAddResult, err := p.api.AddProject(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - return projectAddResult, nil -} - -// DeleteProject . -func (p *Projects) DeleteProject(projectName string) ([]byte, error) { - project := api.Project{ - Name: projectName, - } - returnResult, err := p.api.DeleteProject(project) - return returnResult, err -} - -// UpdateProject . -func (p *Projects) UpdateProject(projectName string, jsonPatch string) ([]byte, error) { - // get the project id from name - projectBName := api.Project{ - Name: projectName, - } - projectByName, err := p.api.GetProjectByName(projectBName, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - projectUpdate, err := processProjectUpdate(projectByName, jsonPatch) - if err != nil { - return []byte(""), err - } - returnResult, err := p.api.UpdateProject(projectUpdate, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processProjectUpdate(projectByName []byte, jsonPatch string) (api.UpdateProject, error) { - var projects api.Project - var projectUpdate api.UpdateProject - var project api.ProjectPatch - err := json.Unmarshal(projectByName, &projects) - if err != nil { - return projectUpdate, err - } - projectID := projects.ID - - // patch the project by id - err = json.Unmarshal([]byte(jsonPatch), &project) - if err != nil { - return projectUpdate, err - } - projectUpdate = api.UpdateProject{ - ID: projectID, - Patch: project, - } - return projectUpdate, nil -} - -// GetProjectKey will get basic info about a project -func (p *Projects) GetProjectKey(projectName string, revealValue bool) ([]byte, error) { - // get project info from lagoon - project := api.Project{ - Name: projectName, - } - keyFragment := `fragment Project on Project { - publicKey - }` - if revealValue { - keyFragment = `fragment Project on Project { - privateKey - publicKey - }` - } - projectByName, err := p.api.GetProjectByName(project, keyFragment) - if err != nil { - return []byte(""), err - } - returnResult, err := processProjectKey(projectByName, revealValue) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processProjectKey(projectByName []byte, revealValue bool) ([]byte, error) { - var project api.Project - err := json.Unmarshal([]byte(projectByName), &project) - if err != nil { - return []byte(""), err - } - // get the key, but strip the newlines we don't need - projectData := []string{ - strings.TrimSuffix(project.PublicKey, "\n"), - } - if revealValue { - projectData = append(projectData, strings.TrimSuffix(project.PrivateKey, "\n")) - } - var data []output.Data - data = append(data, projectData) - dataMain := output.Table{ - Header: []string{"PublicKey"}, - Data: data, - } - if revealValue { - dataMain.Header = append(dataMain.Header, "PrivateKey") - } - return json.Marshal(dataMain) -} diff --git a/pkg/lagoon/projects/main_test.go b/pkg/lagoon/projects/main_test.go deleted file mode 100644 index f14b672f..00000000 --- a/pkg/lagoon/projects/main_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package projects - -import ( - "bytes" - "encoding/json" - "reflect" - "testing" -) - -func checkEqual(t *testing.T, got, want interface{}, msgs ...interface{}) { - if !reflect.DeepEqual(got, want) { - buf := bytes.Buffer{} - buf.WriteString("got:\n[%v]\nwant:\n[%v]\n") - for _, v := range msgs { - buf.WriteString(v.(string)) - } - t.Errorf(buf.String(), got, want) - } -} - -func TestAllProjects(t *testing.T) { - var allProjects = `[ - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/project1.git","id":1,"name":"credentialstest-project1"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/project2.git","id":2,"name":"credentialstest-project2"}, - {"developmentEnvironmentsLimit":5,"environments":[ - {"environmentType":"production","route":null}], - "gitUrl":"ssh://git@192.168.99.1:2222/git/github.git","id":3,"name":"ci-github"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/gitlab.git","id":4,"name":"ci-gitlab"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/nginx.git","id":11,"name":"ci-nginx"}, - {"developmentEnvironmentsLimit":5,"environments":[ - {"environmentType":"production","route":null}], - "gitUrl":"ssh://git@192.168.99.1:2222/git/features.git","id":12,"name":"ci-features"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"git@github.com:uselagoon/lagoon.git","id":13,"name":"lagoon"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/features-subfolder.git","id":17,"name":"ci-features-subfolder"}, - {"developmentEnvironmentsLimit":5,"environments":[ - {"environmentType":"production","route":"http://highcotton.org"}, - {"environmentType":"development","route":"https://varnish-highcotton-org-staging.us.amazee.io"}, - {"environmentType":"development","route":"https://varnish-highcotton-org-development.us.amazee.io"}, - {"environmentType":"development","route":""}, - {"environmentType":"development","route":null}], - "gitUrl":"test","id":18,"name":"high-cotton"}, - {"developmentEnvironmentsLimit":5,"environments":[],"gitUrl":"ssh://git@192.168.99.1:2222/git/api.git","id":21,"name":"ci-api"} -]` - var allProjectsSuccess = `{"header":["ID","ProjectName","GitURL","ProductionEnvironment","DevEnvironments"],"data":[["1","credentialstest-project1","ssh://git@192.168.99.1:2222/git/project1.git","","0/5"],["2","credentialstest-project2","ssh://git@192.168.99.1:2222/git/project2.git","","0/5"],["3","ci-github","ssh://git@192.168.99.1:2222/git/github.git","","0/5"],["4","ci-gitlab","ssh://git@192.168.99.1:2222/git/gitlab.git","","0/5"],["11","ci-nginx","ssh://git@192.168.99.1:2222/git/nginx.git","","0/5"],["12","ci-features","ssh://git@192.168.99.1:2222/git/features.git","","0/5"],["13","lagoon","git@github.com:uselagoon/lagoon.git","","0/5"],["17","ci-features-subfolder","ssh://git@192.168.99.1:2222/git/features-subfolder.git","","0/5"],["18","high-cotton","test","","4/5"],["21","ci-api","ssh://git@192.168.99.1:2222/git/api.git","","0/5"]]}` - - returnResult, err := processAllProjects([]byte(allProjects)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(returnResult) != allProjectsSuccess { - checkEqual(t, string(returnResult), allProjectsSuccess, "allProject processing failed") - } -} - -func TestProjectInfo(t *testing.T) { - var projectInfo = ` - {"autoIdle":1,"branches":"false","developmentEnvironmentsLimit":5,"factsUI":0,"problemsUI":0,"environments":[ - {"deployType":"branch","environmentType":"production","id":3,"name":"Master","openshiftProjectName":"high-cotton-master","route":"http://highcotton.org"}, - {"deployType":"branch","environmentType":"development","id":4,"name":"Staging","openshiftProjectName":"high-cotton-staging","route":"https://varnish-highcotton-org-staging.us.amazee.io"}, - {"deployType":"branch","environmentType":"development","id":5,"name":"Development","openshiftProjectName":"high-cotton-development","route":"https://varnish-highcotton-org-development.us.amazee.io"}, - {"deployType":"pullrequest","environmentType":"development","id":6,"name":"PR-175","openshiftProjectName":"high-cotton-pr-175","route":""}, - {"deployType":"branch","environmentType":"development","id":10,"name":"high-cotton","openshiftProjectName":"high-cotton-high-cotton","route":null}], - "gitUrl":"test","id":18,"name":"high-cotton","productionEnvironment":"doopdd","routerPattern":"${environment}-${project}.lagoon.example.com","pullrequests":"false","storageCalc":1,"subfolder":null}` - var projectInfoSuccess = `{"header":["ID","ProjectName","GitURL","Branches","PullRequests","ProductionRoute","DevEnvironments","DevEnvLimit","ProductionEnv","RouterPattern","AutoIdle","FactsUI","ProblemsUI"],"data":[["18","high-cotton","test","false","false","http://highcotton.org","4/5","5","doopdd","${environment}-${project}.lagoon.example.com","1","0","0"]]}` - - returnResult, err := processProjectInfo([]byte(projectInfo)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(returnResult) != projectInfoSuccess { - checkEqual(t, string(returnResult), projectInfoSuccess, "projectInfo processing failed") - } -} - -func TestProjectUpdate(t *testing.T) { - var updateProject = ` - {"autoIdle":1,"branches":"true","developmentEnvironmentsLimit":5,"environments":[ - {"deployType":"branch","environmentType":"production","id":3,"name":"Master","openshiftProjectName":"high-cotton-master","route":"http://highcotton.org"}, - {"deployType":"branch","environmentType":"development","id":4,"name":"Staging","openshiftProjectName":"high-cotton-staging","route":"https://varnish-highcotton-org-staging.us.amazee.io"}, - {"deployType":"branch","environmentType":"development","id":5,"name":"Development","openshiftProjectName":"high-cotton-development","route":"https://varnish-highcotton-org-development.us.amazee.io"}, - {"deployType":"pullrequest","environmentType":"development","id":6,"name":"PR-175","openshiftProjectName":"high-cotton-pr-175","route":""}, - {"deployType":"branch","environmentType":"development","id":10,"name":"high-cotton","openshiftProjectName":"high-cotton-high-cotton","route":null}], - "gitUrl":"test","id":18,"name":"high-cotton","productionEnvironment":"Master","routerPattern":"${environment}-${project}.lagoon.example.com","pullrequests":"true","storageCalc":1,"subfolder":null}` - - var jsonPatch = `{"branches":"false"}` - var updateProjectsSuccess = `{"id":18,"patch":{"branches":"false"}}` - - var jsonPatchFail = `{"branchesd":"false", "developmentEnvironmentsLimit": 10}` - var updateProjectsFail = `{"id":18,"patch":{"developmentEnvironmentsLimit":10}}` - - returnResult, err := processProjectUpdate([]byte(updateProject), jsonPatch) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - updateResults, err := json.Marshal(returnResult) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(updateResults) != updateProjectsSuccess { - checkEqual(t, string(updateResults), updateProjectsSuccess, "projectInfo processing failed") - } - returnResult, err = processProjectUpdate([]byte(updateProject), jsonPatchFail) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - updateResults, err = json.Marshal(returnResult) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(updateResults) == updateProjectsFail { - checkEqual(t, string(updateResults), updateProjectsFail, "projectInfo processing succeeded, but should fail if json patch is broken") - } -} diff --git a/pkg/lagoon/projects/variables.go b/pkg/lagoon/projects/variables.go deleted file mode 100644 index 53c03f9a..00000000 --- a/pkg/lagoon/projects/variables.go +++ /dev/null @@ -1,143 +0,0 @@ -package projects - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// ListProjectVariables will list the environment variables for a project and all environments attached -func (p *Projects) ListProjectVariables(projectName string, revealValue bool) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - queryFragment := graphql.ProjectEnvVars - if revealValue { - queryFragment = graphql.ProjectEnvVarsRevealed - } - projectByName, err := p.api.GetProjectByName(project, queryFragment) - if err != nil { - return []byte(""), err - } - returnResult, err := processProjectVariables(projectByName, revealValue) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processProjectVariables(projectInfo []byte, revealValue bool) ([]byte, error) { - var project api.Project - err := json.Unmarshal([]byte(projectInfo), &project) - if err != nil { - return []byte(""), err - } - data := []output.Data{} - if len(project.EnvVariables) != 0 { - for _, projectEnvVar := range project.EnvVariables { - envVarRow := []string{ - fmt.Sprintf("%v", projectEnvVar.ID), - project.Name, - projectEnvVar.Scope, - projectEnvVar.Name, - } - if revealValue { - envVarRow = append(envVarRow, projectEnvVar.Value) - } - data = append(data, envVarRow) - } - } - dataMain := output.Table{ - Header: []string{"ID", "Project", "Scope", "VariableName"}, - Data: data, - } - if revealValue { - dataMain.Header = append(dataMain.Header, "VariableValue") - } - return json.Marshal(dataMain) -} - -// AddEnvironmentVariableToProject will list all environments for a project -func (p *Projects) AddEnvironmentVariableToProject(projectName string, envVar api.EnvVariable) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := p.api.GetProjectByName(project, graphql.ProjectByNameFragment) - if err != nil { - return []byte(""), err - } - var projectInfo api.Project - err = json.Unmarshal([]byte(projectByName), &projectInfo) - if err != nil { - return []byte(""), err - } - - // run the query to add the environment variable to lagoon - // we consume the project ID here - customReq := api.CustomRequest{ - Query: `mutation addEnvironmentVariableToProject ($type: EnvVariableType!, $typeId: Int!, $scope: EnvVariableScope!, $name: String!, $value: String!) { - addEnvVariable(input:{type: $type, typeId: $typeId, scope: $scope, name: $name, value: $value}) { - id - } - }`, - Variables: map[string]interface{}{ - "type": api.ProjectVar, - "typeId": projectInfo.ID, - "scope": envVar.Scope, - "name": envVar.Name, - "value": envVar.Value, - }, - MappedResult: "addEnvVariable", - } - returnResult, err := p.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// DeleteEnvironmentVariableFromProject will list all environments for a project -func (p *Projects) DeleteEnvironmentVariableFromProject(projectName string, envVar api.EnvVariable) ([]byte, error) { - // get project info from lagoon, we need the project ID for later - project := api.Project{ - Name: projectName, - } - projectByName, err := p.api.GetProjectByName(project, graphql.ProjectEnvVars) - if err != nil { - return []byte(""), err - } - var envVars api.Project - err = json.Unmarshal([]byte(projectByName), &envVars) - if err != nil { - return []byte(""), err - } - for _, v := range envVars.EnvVariables { - if envVar.Name == v.Name { - envVar.ID = v.ID - break - } - } - if envVar.ID == 0 { - return []byte(""), errors.New("no matching var found") - } - customReq := api.CustomRequest{ - Query: `mutation deleteEnvironmentVariableFromProject ($id: Int!) { - deleteEnvVariable(input:{id: $id}) - }`, - Variables: map[string]interface{}{ - "id": envVar.ID, - }, - MappedResult: "deleteEnvVariable", - } - returnResult, err := p.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} diff --git a/pkg/lagoon/projects/variables_test.go b/pkg/lagoon/projects/variables_test.go deleted file mode 100644 index 8a3443eb..00000000 --- a/pkg/lagoon/projects/variables_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package projects - -import ( - "testing" -) - -func TestListProjectVariables(t *testing.T) { - var all = `{ - "envVariables":[ - {"id":1,"name":"TEST_VAR1","value":"value1","scope":"runtime"}, - {"id":3,"name":"TEST_VAR2","value":"value2","scope":"build"}, - {"id":5,"name":"TEST_VAR3","value":"value3","scope":"build"}, - {"id":7,"name":"TEST_VAR5","value":"value5","scope":"build"} - ],"id":18,"name":"high-cotton" - }` - var allSuccess = `{"header":["ID","Project","Scope","VariableName"],"data":[["1","high-cotton","runtime","TEST_VAR1"],["3","high-cotton","build","TEST_VAR2"],["5","high-cotton","build","TEST_VAR3"],["7","high-cotton","build","TEST_VAR5"]]}` - var allSuccess2 = `{"header":["ID","Project","Scope","VariableName","VariableValue"],"data":[["1","high-cotton","runtime","TEST_VAR1","value1"],["3","high-cotton","build","TEST_VAR2","value2"],["5","high-cotton","build","TEST_VAR3","value3"],["7","high-cotton","build","TEST_VAR5","value5"]]}` - - testResult, err := processProjectVariables([]byte(all), false) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "projectInfo processing failed") - } - testResult, err = processProjectVariables([]byte(all), true) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess2 { - checkEqual(t, string(testResult), allSuccess2, "projectInfo processing failed") - } -} diff --git a/pkg/lagoon/users/groups.go b/pkg/lagoon/users/groups.go deleted file mode 100644 index d9dda749..00000000 --- a/pkg/lagoon/users/groups.go +++ /dev/null @@ -1,272 +0,0 @@ -package users - -import ( - "encoding/json" - "strconv" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// AddGroup function -func (u *Users) AddGroup(group api.Group) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addGroup ($name: String!) { - addGroup(input:{name: $name}) { - id - } - }`, - Variables: map[string]interface{}{ - "name": group.Name, - }, - MappedResult: "addGroup", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// AddGroupWithParent function -func (u *Users) AddGroupWithParent(group api.Group, parent api.Group) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addGroup ($name: String!, $parent: GroupInput) { - addGroup(input:{name: $name}) { - id - } - }`, - Variables: map[string]interface{}{ - "name": group.Name, - "group": parent, - }, - MappedResult: "addGroup", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// AddUserToGroup function -func (u *Users) AddUserToGroup(userGroup api.UserGroupRole) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addUserToGroup($email: String!, $group: String!, $role: GroupRole!) { - addUserToGroup(input:{ - user: { - email: $email - } - group: { - name: $group - } - role: $role - }) - { - id - } - }`, - Variables: map[string]interface{}{ - "email": userGroup.User.Email, - "group": userGroup.Group.Name, - "role": userGroup.Role, - }, - MappedResult: "addUser", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// AddProjectToGroup function -func (u *Users) AddProjectToGroup(groups api.ProjectGroups) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addGroupsToProject($project: String!, $groups: [GroupInput!]!) { - addGroupsToProject(input:{ - groups: $groups - project: {name: $project} - }) { - id - } - }`, - Variables: map[string]interface{}{ - "groups": groups.Groups, - "project": groups.Project.Name, - }, - MappedResult: "addGroupsToProject", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// DeleteGroup function -func (u *Users) DeleteGroup(group api.Group) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation deleteGroup ($name: String!) { - deleteGroup(input:{group:{name: $name}}) - }`, - Variables: map[string]interface{}{ - "name": group.Name, - }, - MappedResult: "deleteGroup", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// RemoveUserFromGroup function -func (u *Users) RemoveUserFromGroup(userGroup api.UserGroup) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation removeUserFromGroup ($email: String!, $group: String!) { - removeUserFromGroup(input:{group:{name: $group} user:{email: $email}}) { - id - } - }`, - Variables: map[string]interface{}{ - "email": userGroup.User.Email, - "group": userGroup.Group.Name, - }, - MappedResult: "removeUserFromGroup", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// RemoveGroupsFromProject function -func (u *Users) RemoveGroupsFromProject(groups api.ProjectGroups) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation removeGroupsFromProject ($project: String!, $groups: [GroupInput!]!) { - removeGroupsFromProject(input:{groups: $groups project:{name: $project}}) { - id - } - }`, - Variables: map[string]interface{}{ - "groups": groups.Groups, - "project": groups.Project.Name, - }, - MappedResult: "removeGroupsFromProject", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// ListGroups function -func (u *Users) ListGroups(name string) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `query allGroups ($name: String) { - allGroups(name: $name) { - id - name - } - }`, - Variables: map[string]interface{}{ - "name": name, - }, - MappedResult: "allGroups", - } - reqResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - returnResult, err := processListGroups(reqResult) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processListGroups(groupData []byte) ([]byte, error) { - var data []output.Data - var groups []struct { - ID string - Name string - } - err := json.Unmarshal(groupData, &groups) - if err != nil { - return []byte(""), err - } - for _, group := range groups { - data = append(data, []string{group.ID, group.Name}) - } - dataMain := output.Table{ - Header: []string{"ID", "Name"}, - Data: data, - } - return json.Marshal(dataMain) -} - -// ListGroupProjects function -func (u *Users) ListGroupProjects(name string, allProjects bool) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `query allGroups ($name: String) { - allGroups(name: $name) { - id - name - projects { - id - name - } - } - }`, - Variables: map[string]interface{}{ - "name": name, - }, - MappedResult: "allGroups", - } - reqResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - returnResult, err := processListGroupProjects(reqResult, allProjects) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processListGroupProjects(groupData []byte, allProjects bool) ([]byte, error) { - var data []output.Data - var groups []struct { - Name string - ID string - Projects []struct { - ID int - Name string - } - } - err := json.Unmarshal(groupData, &groups) - if err != nil { - return []byte(""), err - } - for _, group := range groups { - for _, project := range group.Projects { - projectData := []string{strconv.Itoa(project.ID), project.Name} - if allProjects { - projectData = append(projectData, group.Name) - } - data = append(data, projectData) - } - } - dataMain := output.Table{ - Header: []string{"ID", "ProjectName"}, - Data: data, - } - if allProjects { - dataMain.Header = append(dataMain.Header, "GroupName") - } - return json.Marshal(dataMain) -} diff --git a/pkg/lagoon/users/main.go b/pkg/lagoon/users/main.go deleted file mode 100644 index 588039c2..00000000 --- a/pkg/lagoon/users/main.go +++ /dev/null @@ -1,131 +0,0 @@ -package users - -import ( - "slices" - - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/graphql" -) - -// Users . -type Users struct { - debug bool - api api.Client -} - -// Client . -type Client interface { - AddGroup(api.Group) ([]byte, error) - AddUserToGroup(api.UserGroupRole) ([]byte, error) - AddProjectToGroup(api.ProjectGroups) ([]byte, error) - RemoveUserFromGroup(api.UserGroup) ([]byte, error) - RemoveGroupsFromProject(api.ProjectGroups) ([]byte, error) - DeleteGroup(api.Group) ([]byte, error) - ListUsers(string) ([]byte, error) - AddUser(api.User, bool) ([]byte, error) - AddSSHKeyToUser(api.User, api.SSHKey) ([]byte, error) - DeleteUser(api.User) ([]byte, error) - ModifyUser(api.User, api.User) ([]byte, error) - ListGroups(string) ([]byte, error) - ListGroupProjects(string, bool) ([]byte, error) - ResetPassword(string) ([]byte, error) -} - -// New . -func New(lc *lagoon.Config, debug bool) (Client, error) { - lagoonAPI, err := graphql.LagoonAPI(lc, debug) - if err != nil { - return &Users{}, err - } - return &Users{ - debug: debug, - api: lagoonAPI, - }, nil - -} - -var noDataError = "no data returned from the lagoon api" - -// ExtendedSSHKey . -type ExtendedSSHKey struct { - *api.SSHKey - Email string `json:"email"` -} - -// UserGroup . -type UserGroup struct { - Name string `json:"name"` - ID string `json:"id"` - Role string `json:"role"` -} - -// Data . -type Data struct { - User []UserData -} - -// UserData . -type UserData struct { - ID string `json:"id"` - Email string `json:"email"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - SSHKeys []api.SSHKey `json:"sshKeys"` - Groups []UserGroup `json:"groups"` -} - -// GroupMembers . -type GroupMembers []struct { - ID string `json:"id"` - Members []Member `json:"members"` - Name string `json:"name"` -} - -// Member . -type Member struct { - Role string `json:"role"` - User struct { - ID string `json:"id"` - Email string `json:"email"` - FirstName string `json:"firstName"` - SSHKeys []api.SSHKey `json:"sshKeys"` - LastName string `json:"lastName"` - } `json:"user"` -} - -func returnNonEmptyString(value string) string { - if len(value) == 0 { - value = "-" - } - return value -} - -// AddItem . -func (ud *Data) AddItem(userData UserData) { - ud.User = append(ud.User, userData) -} - -func distinctObjects(objs []UserData) (distinctedObjs []UserData) { - var output []UserData - ids := []string{} - for _, e := range objs { - if !slices.Contains(ids, e.ID) { - ids = append(ids, e.ID) - output = append(output, e) - } - } - return output -} - -func distinctKeys(objs []ExtendedSSHKey) (distinctedObjs []ExtendedSSHKey) { - var output []ExtendedSSHKey - ids := []string{} - for _, e := range objs { - if !slices.Contains(ids, e.Email) { - ids = append(ids, e.Email) - output = append(output, e) - } - } - return output -} diff --git a/pkg/lagoon/users/main_test.go b/pkg/lagoon/users/main_test.go deleted file mode 100644 index c74314cb..00000000 --- a/pkg/lagoon/users/main_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package users - -import ( - "bytes" - "reflect" - "testing" -) - -func checkEqual(t *testing.T, got, want interface{}, msgs ...interface{}) { - if !reflect.DeepEqual(got, want) { - buf := bytes.Buffer{} - buf.WriteString("got:\n[%v]\nwant:\n[%v]\n") - for _, v := range msgs { - buf.WriteString(v.(string)) - } - t.Errorf(buf.String(), got, want) - } -} diff --git a/pkg/lagoon/users/users.go b/pkg/lagoon/users/users.go deleted file mode 100644 index 9fd899ef..00000000 --- a/pkg/lagoon/users/users.go +++ /dev/null @@ -1,277 +0,0 @@ -package users - -import ( - "encoding/json" - "errors" - "strings" - - "github.com/uselagoon/lagoon-cli/pkg/api" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -// AddUser function -func (u *Users) AddUser(user api.User, resetPassword bool) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addUser ($firstname: String, $lastname: String, $email: String!, $resetPassword: Boolean) { - addUser(input:{firstName: $firstname, lastName: $lastname, email: $email, resetPassword: $resetPassword}) { - id - } - }`, - Variables: map[string]interface{}{ - "firstname": user.FirstName, - "lastname": user.LastName, - "email": user.Email, - "resetPassword": resetPassword, - }, - MappedResult: "addUser", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// AddSSHKeyToUser function -func (u *Users) AddSSHKeyToUser(user api.User, sshKey api.SSHKey) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation addSshKey ($email: String!, $keyname: String!, $keyvalue: String!, $keytype: SshKeyType!) { - addSshKey(input:{ - user: { - email: $email - } - name: $keyname - keyValue: $keyvalue - keyType: $keytype - }) { - id - } - }`, - Variables: map[string]interface{}{ - "email": user.Email, - "keyname": sshKey.Name, - "keyvalue": sshKey.KeyValue, - "keytype": sshKey.KeyType, - }, - MappedResult: "addSshKey", - } - 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{ - Query: `mutation deleteUser ($email: String!) { - deleteUser(input:{user: {email: $email}}) - }`, - Variables: map[string]interface{}{ - "email": user.Email, - }, - MappedResult: "deleteUser", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// ModifyUser function -func (u *Users) ModifyUser(user api.User, patch api.User) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation updateUser ($email: String!, $patch: UpdateUserPatchInput!) { - updateUser(input:{ - user:{email: $email} - patch: $patch - }){ - id - } - }`, - Variables: map[string]interface{}{ - "patch": patch, - "email": user.Email, - }, - MappedResult: "updateUser", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -// ListUsers function -func (u *Users) ListUsers(groupName string) ([]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 - } - role - } - } - }`, - Variables: map[string]interface{}{ - "name": groupName, - }, - MappedResult: "allGroups", - } - listUsers, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - returnResult, err := processUserList(listUsers) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func (u *Users) ResetPassword(email string) ([]byte, error) { - customReq := api.CustomRequest{ - Query: `mutation resetPassword ($email: String!) { - resetUserPassword (input: { user: { email: $email } }) - }`, - Variables: map[string]interface{}{ - "email": email, - }, - MappedResult: "resetUserPassword", - } - returnResult, err := u.api.Request(customReq) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processUserList(listUsers []byte) ([]byte, error) { - var groupMembers GroupMembers - err := json.Unmarshal([]byte(listUsers), &groupMembers) - if err != nil { - return []byte(""), errors.New(noDataError) // @TODO could be a permissions thing when no data is returned - } - // process the data for output - data := []output.Data{} - userDataStep1 := Data{} - userDataStep2 := Data{} - - // initial sort to change group members to members with groups - for _, group := range groupMembers { - for _, member := range group.Members { - userDataStep1.AddItem(UserData{ID: member.User.ID, Email: member.User.Email, FirstName: member.User.FirstName, LastName: member.User.LastName}) - } - } - // second sort to append the groups to the user data - for _, usersData := range userDataStep1.User { - userGroups := []UserGroup{} - for _, group := range groupMembers { - for _, member := range group.Members { - if member.User.Email == usersData.Email { - userGroups = append(userGroups, UserGroup{Name: group.Name, Role: member.Role}) - } - } - } - usersData.Groups = userGroups - userDataStep2.User = append(userDataStep2.User, usersData) - } - // finally display the re-sorted users with group information - for _, i := range distinctObjects(userDataStep2.User) { - for _, group := range i.Groups { - userID := returnNonEmptyString(i.ID) - userEmail := returnNonEmptyString(strings.Replace(i.Email, " ", "_", -1)) //remove spaces to make friendly for parsing with awk - userFirstName := returnNonEmptyString(strings.Replace(i.FirstName, " ", "_", -1)) - userLastName := returnNonEmptyString(strings.Replace(i.LastName, " ", "_", -1)) - userGroup := returnNonEmptyString(strings.Replace(group.Name, " ", "_", -1)) - userRole := returnNonEmptyString(strings.Replace(group.Role, " ", "_", -1)) - data = append(data, []string{ - userID, - userEmail, - userFirstName, - userLastName, - userGroup, - userRole, - }) - } - } - dataMain := output.Table{ - Header: []string{"ID", "Name", "FirstName", "LastName", "Group", "Role"}, - Data: data, - } - return json.Marshal(dataMain) -} - -func processReturnedUserKeysList(listUsers []byte) ([]ExtendedSSHKey, error) { - var groupMembers GroupMembers - userDataStep1 := []ExtendedSSHKey{} - err := json.Unmarshal([]byte(listUsers), &groupMembers) - if err != nil { - return userDataStep1, errors.New(noDataError) // @TODO could be a permissions thing when no data is returned - } - // initial sort to change group members to members with groups - for _, group := range groupMembers { - for _, member := range group.Members { - for _, key := range member.User.SSHKeys { - userDataStep1 = append(userDataStep1, ExtendedSSHKey{SSHKey: &key, Email: member.User.Email}) - } - } - } - return userDataStep1, nil -} - -func processAllUserKeysList(listUsers []ExtendedSSHKey) ([]byte, error) { - // second sort to append the groups to the user data - data := []output.Data{} - for _, usersData := range distinctKeys(listUsers) { - userEmail := returnNonEmptyString(strings.Replace(usersData.Email, " ", "_", -1)) //remove spaces to make friendly for parsing with awk - keyName := returnNonEmptyString(strings.Replace(usersData.SSHKey.Name, " ", "_", -1)) - keyValue := returnNonEmptyString(strings.Replace(usersData.SSHKey.KeyValue, " ", "_", -1)) - keyType := returnNonEmptyString(strings.Replace(string(usersData.SSHKey.KeyType), " ", "_", -1)) - data = append(data, []string{ - userEmail, - keyName, - keyType, - keyValue, - }) - } - dataMain := output.Table{ - Header: []string{"Email", "Name", "Type", "Value"}, - Data: data, - } - return json.Marshal(dataMain) -} - -func processUserKeysList(listUsers []ExtendedSSHKey, email string) ([]byte, error) { - // second sort to append the groups to the user data - data := []output.Data{} - for _, usersData := range distinctKeys(listUsers) { - if usersData.Email == email { - userEmail := returnNonEmptyString(strings.Replace(usersData.Email, " ", "_", -1)) //remove spaces to make friendly for parsing with awk - keyName := returnNonEmptyString(strings.Replace(usersData.SSHKey.Name, " ", "_", -1)) - keyValue := returnNonEmptyString(strings.Replace(usersData.SSHKey.KeyValue, " ", "_", -1)) - keyType := returnNonEmptyString(strings.Replace(string(usersData.SSHKey.KeyType), " ", "_", -1)) - data = append(data, []string{ - userEmail, - keyName, - keyType, - keyValue, - }) - } - } - dataMain := output.Table{ - Header: []string{"Email", "Name", "Type", "Value"}, - Data: data, - } - return json.Marshal(dataMain) -} diff --git a/pkg/lagoon/users/users_test.go b/pkg/lagoon/users/users_test.go deleted file mode 100644 index 01ff2f90..00000000 --- a/pkg/lagoon/users/users_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package users - -import ( - "testing" -) - -func TestListUsers(t *testing.T) { - var userList = `[{"id":"21ab7da7-4dc7-4745-92ef-a9faf663b8a4","members":[],"name":"High Cotton Billing Group"},{"id":"07b3d263-3a3e-4d0e-ac3f-56eab1e80df9","members":[{"role":"OWNER","user":{"email":"ci-customer-user-ed25519@example.com","firstName":null,"id":"23781ccd-8e35-4206-a7cf-97153311ba91","lastName":null}},{"role":"OWNER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"ci-group"},{"id":"f6786ff8-4eea-476a-8462-25931c0b2724","members":[{"role":"OWNER","user":{"email":"credentialtestbothgroupaccess_user@example.com","firstName":null,"id":"678707fd-0d01-458d-981f-acae396624bb","lastName":null}}],"name":"credentialtest-group1"},{"id":"8349ffb3-d940-445e-a610-4bb6f3ba8a0f","members":[{"role":"OWNER","user":{"email":"credentialtestbothgroupaccess_user@example.com","firstName":null,"id":"678707fd-0d01-458d-981f-acae396624bb","lastName":null}}],"name":"credentialtest-group2"},{"id":"ec16cf3e-47a9-4aed-825a-5ac5b39acb3d","members":[],"name":"kickstart-group"},{"id":"94311670-e817-4335-b440-25a92e1ac83f","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-api"},{"id":"2d3968f0-36f0-4082-9f02-1dbf86ce410e","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-bitbucket"},{"id":"6ede38ac-b54d-43c2-a4ad-a949eb05edc6","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-drupal"},{"id":"64bd6e32-b3f2-48d5-8a24-bb553d397891","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-drupal-galera"},{"id":"6ef3300b-0e5a-4acc-9b83-4848b295dba4","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-drupal-postgres"},{"id":"aa5d4e8a-c330-4208-bf9a-b9cb3fda7373","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-elasticsearch"},{"id":"a21de1e1-fb3e-4a8c-adcb-f05b6a5b3d98","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-env-limit"},{"id":"60f0103a-a4ea-4dad-b5c7-da786ffa9db8","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-features"},{"id":"68e35dd0-5b0f-4284-8559-065e87f5ce06","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-features-subfolder"},{"id":"c5ca68de-fb5a-4b5e-9005-dd737132acad","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-github"},{"id":"fb1e5d7b-0326-4c81-a1d3-20bbc7de2dc3","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-gitlab"},{"id":"cc5cbaf6-0fc6-40e7-9e07-ff974a65979d","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-multiproject1"},{"id":"54c83c15-1359-44f9-b72f-40401f4f9ae9","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-multiproject2"},{"id":"8bcc7d64-76cb-4ed3-ba14-ce28db8655c8","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-nginx"},{"id":"a9e5c8bb-e201-408f-b7b9-e3dacd648461","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-node"},{"id":"190fc14f-76e4-453f-aefe-473dc4318892","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-rest"},{"id":"ba8abffe-2cea-4315-b788-081a51017290","members":[{"role":"MAINTAINER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null}}],"name":"project-ci-solr"},{"id":"13d15964-4bc3-4e05-aa91-b4ec8a07909a","members":[{"role":"MAINTAINER","user":{"email":"default-user@credentialstest-project1","firstName":null,"id":"f483d9e9-0f1d-4700-bdeb-80b62f89451f","lastName":null}}],"name":"project-credentialstest-project1"},{"id":"fbca7521-aab5-4f60-98e9-8e299439b3e5","members":[{"role":"MAINTAINER","user":{"email":"default-user@credentialstest-project2","firstName":null,"id":"250c1384-c41c-475e-ac7f-5c36d8defc10","lastName":null}}],"name":"project-credentialstest-project2"},{"id":"061fa7d7-5f5c-4ff5-8492-cc99f2250b37","members":[{"role":"MAINTAINER","user":{"email":"default-user@credentialstest-project3","firstName":null,"id":"48947347-ed80-42d4-b070-6c80a3463ec3","lastName":null}}],"name":"project-credentialstest-project3"},{"id":"41e54119-65ba-463f-b2bf-7b5e6575bd27","members":[{"role":"MAINTAINER","user":{"email":"default-user@high-cotton","firstName":null,"id":"ca1ed845-6200-4456-912a-6c3dc162448a","lastName":null}}],"name":"project-high-cotton"},{"id":"cc24ba9b-a39b-48dc-9602-f945d0c2ec69","members":[{"role":"MAINTAINER","user":{"email":"default-user@lagoon","firstName":null,"id":"840671ce-fe85-4d60-ba0a-bb63502955a8","lastName":null}}],"name":"project-lagoon"},{"id":"8140f065-a606-4827-a454-2c9bc4513975","members":[],"name":"ui-customer"}]` - var allSuccess = `{"header":["ID","Name","FirstName","LastName","Group","Role"],"data":[["23781ccd-8e35-4206-a7cf-97153311ba91","ci-customer-user-ed25519@example.com","-","-","ci-group","OWNER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","ci-group","OWNER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-api","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-bitbucket","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-drupal","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-drupal-galera","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-drupal-postgres","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-elasticsearch","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-env-limit","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-features","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-features-subfolder","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-github","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-gitlab","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-multiproject1","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-multiproject2","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-nginx","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-node","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-rest","MAINTAINER"],["906391b3-b3b2-43cb-82e7-fa0c07007fbc","ci-customer-user-rsa@example.com","-","-","project-ci-solr","MAINTAINER"],["678707fd-0d01-458d-981f-acae396624bb","credentialtestbothgroupaccess_user@example.com","-","-","credentialtest-group1","OWNER"],["678707fd-0d01-458d-981f-acae396624bb","credentialtestbothgroupaccess_user@example.com","-","-","credentialtest-group2","OWNER"],["f483d9e9-0f1d-4700-bdeb-80b62f89451f","default-user@credentialstest-project1","-","-","project-credentialstest-project1","MAINTAINER"],["250c1384-c41c-475e-ac7f-5c36d8defc10","default-user@credentialstest-project2","-","-","project-credentialstest-project2","MAINTAINER"],["48947347-ed80-42d4-b070-6c80a3463ec3","default-user@credentialstest-project3","-","-","project-credentialstest-project3","MAINTAINER"],["ca1ed845-6200-4456-912a-6c3dc162448a","default-user@high-cotton","-","-","project-high-cotton","MAINTAINER"],["840671ce-fe85-4d60-ba0a-bb63502955a8","default-user@lagoon","-","-","project-lagoon","MAINTAINER"]]}` - - testResult, err := processUserList([]byte(userList)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "list user processing failed") - } -} -func TestListUserKeys(t *testing.T) { - var userList = `[{"id":"07b3d263-3a3e-4d0e-ac3f-56eab1e80df9","members":[{"role":"MAINTAINER","user":{"email":"c@c.com","firstName":"bob","id":"a08f166e-64f0-4461-9daa-e62b6f414faf","lastName":"bob","sshKeys":[{"keyType":"ssh-rsa","keyValue":"AAAAB3NzaC1yc2EAAAADAQABAAACAQC++bRFdPP6d3kdXv1eImtfSgHhumcsy4IhAYId23v85nmcnTMqA5ahCoOzChPuxKWVsTGaU3xh+PMkQAO/HAkyUYIK8VlIMP/w9+VYraOYHwCZBZqiKwJH6XjpX24qTzdNYU8WdC+6OdOV+0SrEdtduxJV/TnVkoe+Ga+y7013mxCbw5y9LIPs/eBXjwuN/lASxaZGpzAP5FipKC/HOC+oS96gaNVQgmWl3Lm+faGpq2V1afEE9A0RXYhvQ6qG9qvcmFGtqLyhu6m7i9tjNiTlXalsFeox0pu8cnFvKZZZnFwi1EI4ngBUUg/hTFWmr13F2TslEJrnCqm8efs6o40l3tsdD64Jr1q9LUvqKWrwrv4B2vM2O3iccaE5Ll7fNH4pRDTZpFRL92MoX+TBpPjLxFYhz5zOJUKiFMsERkHJB/28a2BPU2etThwkIy5EwOrwHl/Q2KMxrddwwfd9FAZnmHXoUA0OtcZtgyrBDECOzuleGSyhcbXynQBwiEJ1RRQrbeWBTberQi4v+rDKgauxxVyfxH4yQfkoAFwt+QjQPUWv/kKCS+8LEJv1QlEd0lNh2A+TO/ugmsdshO+PzYKUtm4wMiqo0XfzyJGJFvYKbUbPNSZ7iGPRKkwQot8UQgAY/jwXn6z1sm8VmwDLirP1IUIHdt8pGarTffufPd9Rww==","name":"deploy@nhmrc"}]}},{"role":"OWNER","user":{"email":"ci-customer-user-ed25519@example.com","firstName":null,"id":"23781ccd-8e35-4206-a7cf-97153311ba91","lastName":null,"sshKeys":[{"keyType":"ssh-ed25519","keyValue":"AAAAC3NzaC1lZDI1NTE5AAAAIMdEs1h19jv2UrbtKcqPDatUxT9lPYcbGlEAbInsY8Ka","name":"ci-customer-sshkey-ed25519"}]}},{"role":"MAINTAINER","user":{"email":"ci-customer-ecdsa-521@example.com","firstName":null,"id":"a08f166e-64f0-4461-9daa-e62b6f414faf","lastName":null,"sshKeys":[{"keyType":"ecdsa-sha2-nistp521","keyValue":"AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFAX0rkOBwlrXr2rJNxYVi0fRj8IiHBaFCsAM0zO+o2fh+h4EuL1Mx4F237SX5G0zuL8R6Sbf9LrY2lhKZdDpiFdgF7pP1TZ8RuDvKgasppGDEzAIm9+7bmHR118CejWF7llgHD3oz+/aRHTZVpOOaCyTGkF2oPeUejrI74KoPHk3HHpQ==","name":"ci-customer-ecdsa-521"}]}},{"role":"OWNER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null,"sshKeys":[{"keyType":"ssh-rsa","keyValue":"AAAAB3NzaC1yc2EAAAADAQABAAACAQDEZlms5XsiyWjmnnUyhpt93VgHypse9Bl8kNkmZJTiM3Ex/wZAfwogzqd2LrTEiIOWSH1HnQazR+Cc9oHCmMyNxRrLkS/MEl0yZ38Q+GDfn37h/llCIZNVoHlSgYkqD0MQrhfGL5AulDUKIle93dA6qdCUlnZZjDPiR0vEXR36xGuX7QYAhK30aD2SrrBruTtFGvj87IP/0OEOvUZe8dcU9G/pCoqrTzgKqJRpqs/s5xtkqLkTIyR/SzzplO21A+pCKNax6csDDq3snS8zfx6iM8MwVfh8nvBW9seax1zBvZjHAPSTsjzmZXm4z32/ujAn/RhIkZw3ZgRKrxzryttGnWJJ8OFyF31JTJgwWWuPdH53G15PC83ZbmEgSV3win51RZRVppN4uQUuaqZWG9wwk2a6P5aen1RLCSLpTkd2mAEk9PlgmJrf8vITkiU9pF9n68ENCoo556qSdxW2pxnjrzKVPSqmqO1Xg5K4LOX4/9N4n4qkLEOiqnzzJClhFif3O28RW86RPxERGdPT81UI0oDAcU5euQr8Emz+Hd+PY1115UIld3CIHib5PYL9Ee0bFUKiWpR/acSe1fHB64mCoHP7hjFepGsq7inkvg2651wUDKBshGltpNkMj6+aZedNc0/rKYyjl80nT8g8QECgOSRzpmYp0zli2HpFoLOiWw==","name":"ci-customer-sshkey-rsa"}]}}],"name":"ci-group"}]` - var allSuccess = `{"header":["Email","Name","Type","Value"],"data":[["c@c.com","deploy@nhmrc","ssh-rsa","AAAAB3NzaC1yc2EAAAADAQABAAACAQC++bRFdPP6d3kdXv1eImtfSgHhumcsy4IhAYId23v85nmcnTMqA5ahCoOzChPuxKWVsTGaU3xh+PMkQAO/HAkyUYIK8VlIMP/w9+VYraOYHwCZBZqiKwJH6XjpX24qTzdNYU8WdC+6OdOV+0SrEdtduxJV/TnVkoe+Ga+y7013mxCbw5y9LIPs/eBXjwuN/lASxaZGpzAP5FipKC/HOC+oS96gaNVQgmWl3Lm+faGpq2V1afEE9A0RXYhvQ6qG9qvcmFGtqLyhu6m7i9tjNiTlXalsFeox0pu8cnFvKZZZnFwi1EI4ngBUUg/hTFWmr13F2TslEJrnCqm8efs6o40l3tsdD64Jr1q9LUvqKWrwrv4B2vM2O3iccaE5Ll7fNH4pRDTZpFRL92MoX+TBpPjLxFYhz5zOJUKiFMsERkHJB/28a2BPU2etThwkIy5EwOrwHl/Q2KMxrddwwfd9FAZnmHXoUA0OtcZtgyrBDECOzuleGSyhcbXynQBwiEJ1RRQrbeWBTberQi4v+rDKgauxxVyfxH4yQfkoAFwt+QjQPUWv/kKCS+8LEJv1QlEd0lNh2A+TO/ugmsdshO+PzYKUtm4wMiqo0XfzyJGJFvYKbUbPNSZ7iGPRKkwQot8UQgAY/jwXn6z1sm8VmwDLirP1IUIHdt8pGarTffufPd9Rww=="],["ci-customer-user-ed25519@example.com","ci-customer-sshkey-ed25519","ssh-ed25519","AAAAC3NzaC1lZDI1NTE5AAAAIMdEs1h19jv2UrbtKcqPDatUxT9lPYcbGlEAbInsY8Ka"],["ci-customer-ecdsa-521@example.com","ci-customer-ecdsa-521","ecdsa-sha2-nistp521","AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFAX0rkOBwlrXr2rJNxYVi0fRj8IiHBaFCsAM0zO+o2fh+h4EuL1Mx4F237SX5G0zuL8R6Sbf9LrY2lhKZdDpiFdgF7pP1TZ8RuDvKgasppGDEzAIm9+7bmHR118CejWF7llgHD3oz+/aRHTZVpOOaCyTGkF2oPeUejrI74KoPHk3HHpQ=="],["ci-customer-user-rsa@example.com","ci-customer-sshkey-rsa","ssh-rsa","AAAAB3NzaC1yc2EAAAADAQABAAACAQDEZlms5XsiyWjmnnUyhpt93VgHypse9Bl8kNkmZJTiM3Ex/wZAfwogzqd2LrTEiIOWSH1HnQazR+Cc9oHCmMyNxRrLkS/MEl0yZ38Q+GDfn37h/llCIZNVoHlSgYkqD0MQrhfGL5AulDUKIle93dA6qdCUlnZZjDPiR0vEXR36xGuX7QYAhK30aD2SrrBruTtFGvj87IP/0OEOvUZe8dcU9G/pCoqrTzgKqJRpqs/s5xtkqLkTIyR/SzzplO21A+pCKNax6csDDq3snS8zfx6iM8MwVfh8nvBW9seax1zBvZjHAPSTsjzmZXm4z32/ujAn/RhIkZw3ZgRKrxzryttGnWJJ8OFyF31JTJgwWWuPdH53G15PC83ZbmEgSV3win51RZRVppN4uQUuaqZWG9wwk2a6P5aen1RLCSLpTkd2mAEk9PlgmJrf8vITkiU9pF9n68ENCoo556qSdxW2pxnjrzKVPSqmqO1Xg5K4LOX4/9N4n4qkLEOiqnzzJClhFif3O28RW86RPxERGdPT81UI0oDAcU5euQr8Emz+Hd+PY1115UIld3CIHib5PYL9Ee0bFUKiWpR/acSe1fHB64mCoHP7hjFepGsq7inkvg2651wUDKBshGltpNkMj6+aZedNc0/rKYyjl80nT8g8QECgOSRzpmYp0zli2HpFoLOiWw=="]]}` - - processedList, err := processReturnedUserKeysList([]byte(userList)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - testResult, err := processAllUserKeysList(processedList) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "list sshkeys processing failed") - } -} -func TestListSpecificUserKeys(t *testing.T) { - var testUser = `c@c.com` - var userList = `[{"id":"07b3d263-3a3e-4d0e-ac3f-56eab1e80df9","members":[{"role":"MAINTAINER","user":{"email":"c@c.com","firstName":"bob","id":"a08f166e-64f0-4461-9daa-e62b6f414faf","lastName":"bob","sshKeys":[{"keyType":"ssh-rsa","keyValue":"AAAAB3NzaC1yc2EAAAADAQABAAACAQC++bRFdPP6d3kdXv1eImtfSgHhumcsy4IhAYId23v85nmcnTMqA5ahCoOzChPuxKWVsTGaU3xh+PMkQAO/HAkyUYIK8VlIMP/w9+VYraOYHwCZBZqiKwJH6XjpX24qTzdNYU8WdC+6OdOV+0SrEdtduxJV/TnVkoe+Ga+y7013mxCbw5y9LIPs/eBXjwuN/lASxaZGpzAP5FipKC/HOC+oS96gaNVQgmWl3Lm+faGpq2V1afEE9A0RXYhvQ6qG9qvcmFGtqLyhu6m7i9tjNiTlXalsFeox0pu8cnFvKZZZnFwi1EI4ngBUUg/hTFWmr13F2TslEJrnCqm8efs6o40l3tsdD64Jr1q9LUvqKWrwrv4B2vM2O3iccaE5Ll7fNH4pRDTZpFRL92MoX+TBpPjLxFYhz5zOJUKiFMsERkHJB/28a2BPU2etThwkIy5EwOrwHl/Q2KMxrddwwfd9FAZnmHXoUA0OtcZtgyrBDECOzuleGSyhcbXynQBwiEJ1RRQrbeWBTberQi4v+rDKgauxxVyfxH4yQfkoAFwt+QjQPUWv/kKCS+8LEJv1QlEd0lNh2A+TO/ugmsdshO+PzYKUtm4wMiqo0XfzyJGJFvYKbUbPNSZ7iGPRKkwQot8UQgAY/jwXn6z1sm8VmwDLirP1IUIHdt8pGarTffufPd9Rww==","name":"deploy@nhmrc"}]}},{"role":"OWNER","user":{"email":"ci-customer-user-ed25519@example.com","firstName":null,"id":"23781ccd-8e35-4206-a7cf-97153311ba91","lastName":null,"sshKeys":[{"keyType":"ssh-ed25519","keyValue":"AAAAC3NzaC1lZDI1NTE5AAAAIMdEs1h19jv2UrbtKcqPDatUxT9lPYcbGlEAbInsY8Ka","name":"ci-customer-sshkey-ed25519"}]}},{"role":"MAINTAINER","user":{"email":"ci-customer-ecdsa-521","firstName":null,"id":"a08f166e-64f0-4461-9daa-e62b6f414faf","lastName":null,"sshKeys":[{"keyType":"ecdsa-sha2-nistp521","keyValue":"AAAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFAX0rkOBwlrXr2rJNxYVi0fRj8IiHBaFCsAM0zO+o2fh+h4EuL1Mx4F237SX5G0zuL8R6Sbf9LrY2lhKZdDpiFdgF7pP1TZ8RuDvKgasppGDEzAIm9+7bmHR118CejWF7llgHD3oz+/aRHTZVpOOaCyTGkF2oPeUejrI74KoPHk3HHpQ==","name":"ci-customer-ecdsa-521"}]}},{"role":"OWNER","user":{"email":"ci-customer-user-rsa@example.com","firstName":null,"id":"906391b3-b3b2-43cb-82e7-fa0c07007fbc","lastName":null,"sshKeys":[{"keyType":"ssh-rsa","keyValue":"AAAAB3NzaC1yc2EAAAADAQABAAACAQDEZlms5XsiyWjmnnUyhpt93VgHypse9Bl8kNkmZJTiM3Ex/wZAfwogzqd2LrTEiIOWSH1HnQazR+Cc9oHCmMyNxRrLkS/MEl0yZ38Q+GDfn37h/llCIZNVoHlSgYkqD0MQrhfGL5AulDUKIle93dA6qdCUlnZZjDPiR0vEXR36xGuX7QYAhK30aD2SrrBruTtFGvj87IP/0OEOvUZe8dcU9G/pCoqrTzgKqJRpqs/s5xtkqLkTIyR/SzzplO21A+pCKNax6csDDq3snS8zfx6iM8MwVfh8nvBW9seax1zBvZjHAPSTsjzmZXm4z32/ujAn/RhIkZw3ZgRKrxzryttGnWJJ8OFyF31JTJgwWWuPdH53G15PC83ZbmEgSV3win51RZRVppN4uQUuaqZWG9wwk2a6P5aen1RLCSLpTkd2mAEk9PlgmJrf8vITkiU9pF9n68ENCoo556qSdxW2pxnjrzKVPSqmqO1Xg5K4LOX4/9N4n4qkLEOiqnzzJClhFif3O28RW86RPxERGdPT81UI0oDAcU5euQr8Emz+Hd+PY1115UIld3CIHib5PYL9Ee0bFUKiWpR/acSe1fHB64mCoHP7hjFepGsq7inkvg2651wUDKBshGltpNkMj6+aZedNc0/rKYyjl80nT8g8QECgOSRzpmYp0zli2HpFoLOiWw==","name":"ci-customer-sshkey-rsa"}]}}],"name":"ci-group"}]` - var allSuccess = `{"header":["Email","Name","Type","Value"],"data":[["c@c.com","deploy@nhmrc","ssh-rsa","AAAAB3NzaC1yc2EAAAADAQABAAACAQC++bRFdPP6d3kdXv1eImtfSgHhumcsy4IhAYId23v85nmcnTMqA5ahCoOzChPuxKWVsTGaU3xh+PMkQAO/HAkyUYIK8VlIMP/w9+VYraOYHwCZBZqiKwJH6XjpX24qTzdNYU8WdC+6OdOV+0SrEdtduxJV/TnVkoe+Ga+y7013mxCbw5y9LIPs/eBXjwuN/lASxaZGpzAP5FipKC/HOC+oS96gaNVQgmWl3Lm+faGpq2V1afEE9A0RXYhvQ6qG9qvcmFGtqLyhu6m7i9tjNiTlXalsFeox0pu8cnFvKZZZnFwi1EI4ngBUUg/hTFWmr13F2TslEJrnCqm8efs6o40l3tsdD64Jr1q9LUvqKWrwrv4B2vM2O3iccaE5Ll7fNH4pRDTZpFRL92MoX+TBpPjLxFYhz5zOJUKiFMsERkHJB/28a2BPU2etThwkIy5EwOrwHl/Q2KMxrddwwfd9FAZnmHXoUA0OtcZtgyrBDECOzuleGSyhcbXynQBwiEJ1RRQrbeWBTberQi4v+rDKgauxxVyfxH4yQfkoAFwt+QjQPUWv/kKCS+8LEJv1QlEd0lNh2A+TO/ugmsdshO+PzYKUtm4wMiqo0XfzyJGJFvYKbUbPNSZ7iGPRKkwQot8UQgAY/jwXn6z1sm8VmwDLirP1IUIHdt8pGarTffufPd9Rww=="]]}` - - processedList, err := processReturnedUserKeysList([]byte(userList)) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - testResult, err := processUserKeysList(processedList, testUser) - if err != nil { - t.Error("Should not fail if processing succeeded", err) - } - if string(testResult) != allSuccess { - checkEqual(t, string(testResult), allSuccess, "list specific user sshkeys processing failed") - } -} diff --git a/pkg/output/main.go b/pkg/output/main.go index 2465336d..855c17c1 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/jedib0t/go-pretty/v6/table" - "github.com/jedib0t/go-pretty/v6/text" "github.com/logrusorgru/aurora" ) @@ -22,12 +21,13 @@ type Data []string // Options . type Options struct { - Header bool - CSV bool - JSON bool - Pretty bool - Debug bool - Error string + Header bool + CSV bool + JSON bool + Pretty bool + Debug bool + Error string + MultiLine bool } // Result . @@ -151,8 +151,9 @@ func RenderOutput(data Table, opts Options) { t.Style().Options = table.OptionsNoBordersAndSeparators t.Style().Box.PaddingLeft = "" // trim left space t.Style().Box.PaddingRight = "\t" // pad right with tab - t.SuppressTrailingSpaces() // suppress the trailing spaces - t.SetColumnConfigs([]table.ColumnConfig{{Align: text.AlignLeft}}) + if !opts.MultiLine { + t.SuppressTrailingSpaces() // suppress the trailing spaces if not multiline + } if opts.CSV { t.RenderCSV() return