From 3f436b745a08c5bafe80be79d2902e46650eb673 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 21 Jun 2024 17:48:31 +1000 Subject: [PATCH 1/3] refactor: output package return string --- cmd/config.go | 6 ++- cmd/deploytarget.go | 15 ++++-- cmd/deploytargetconfig.go | 9 ++-- cmd/environment.go | 9 ++-- cmd/get.go | 24 ++++++---- cmd/groups.go | 18 ++++--- cmd/list.go | 85 ++++++++++++++++++++++------------ cmd/notificationsemail.go | 21 ++++++--- cmd/notificationsrocketchat.go | 21 ++++++--- cmd/notificationsslack.go | 21 ++++++--- cmd/notificationsteams.go | 21 ++++++--- cmd/notificationswebhook.go | 21 ++++++--- cmd/organization.go | 9 ++-- cmd/project.go | 24 ++++++---- cmd/tasks.go | 21 ++++++--- cmd/users.go | 30 ++++++++---- cmd/variables.go | 6 ++- cmd/whoami.go | 6 ++- pkg/output/main.go | 35 +++++++------- 19 files changed, 263 insertions(+), 139 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index aee6e242..d8919fd3 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -129,10 +129,11 @@ var configLagoonsCmd = &cobra.Command{ tableHeader = append(tableHeader, "Kibana-URL") } tableHeader = append(tableHeader, "SSH-Key") - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: tableHeader, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -168,7 +169,7 @@ var configAddCmd = &cobra.Command{ if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { return fmt.Errorf("couldn't write config: %v", err) } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "GraphQL", @@ -190,6 +191,7 @@ var configAddCmd = &cobra.Command{ }, }, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { return fmt.Errorf("must have Hostname, Port, and GraphQL endpoint") } diff --git a/cmd/deploytarget.go b/cmd/deploytarget.go index b4f9d27e..105ab640 100644 --- a/cmd/deploytarget.go +++ b/cmd/deploytarget.go @@ -120,7 +120,7 @@ var addDeployTargetCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", addDeployTargetResponse.Created)), returnNonEmptyString(fmt.Sprintf("%v", addDeployTargetResponse.MonitoringConfig)), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -138,6 +138,7 @@ var addDeployTargetCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -252,7 +253,7 @@ var updateDeployTargetCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", updateDeployTargetResponse.Created)), returnNonEmptyString(fmt.Sprintf("%v", updateDeployTargetResponse.MonitoringConfig)), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -270,6 +271,7 @@ var updateDeployTargetCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -319,7 +321,8 @@ var deleteDeployTargetCmd = &cobra.Command{ resultData := output.Result{ Result: deleteDeployTargetResponse.DeleteDeployTarget, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -383,7 +386,8 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ "Organization Name": deployTargetResponse.Name, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -447,7 +451,8 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/deploytargetconfig.go b/cmd/deploytargetconfig.go index cb4465f3..a033bef1 100644 --- a/cmd/deploytargetconfig.go +++ b/cmd/deploytargetconfig.go @@ -90,7 +90,7 @@ var addDeployTargetConfigCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", deployTargetConfig.DeployTarget.CloudProvider)), returnNonEmptyString(fmt.Sprintf("%v", deployTargetConfig.DeployTarget.CloudRegion)), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Weight", @@ -103,6 +103,7 @@ var addDeployTargetConfigCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -184,7 +185,7 @@ var updateDeployTargetConfigCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", deployTargetConfig.DeployTarget.CloudProvider)), returnNonEmptyString(fmt.Sprintf("%v", deployTargetConfig.DeployTarget.CloudRegion)), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Weight", @@ -197,6 +198,7 @@ var updateDeployTargetConfigCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -306,7 +308,7 @@ var listDeployTargetConfigsCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", deployTargetConfig.DeployTarget.CloudRegion)), }) } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Weight", @@ -319,6 +321,7 @@ var listDeployTargetConfigsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/environment.go b/cmd/environment.go index 7875b94f..704dd785 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -50,7 +50,8 @@ var deleteEnvCmd = &cobra.Command{ resultData := output.Result{ Result: environment.DeleteEnvironment, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -172,7 +173,8 @@ var updateEnvironmentCmd = &cobra.Command{ "Environment Name": result.Name, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -233,7 +235,7 @@ var listBackupsCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", backup.Restore.Status)), }) } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "BackupID", "Source", @@ -243,6 +245,7 @@ var listBackupsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/get.go b/cmd/get.go index bcccbe8c..6c838451 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -60,7 +60,8 @@ var getProjectCmd = &cobra.Command{ if project.Name == "" { outputOptions.Error = fmt.Sprintf("No details for project '%s'\n", cmdProjectName) - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -112,7 +113,8 @@ var getProjectCmd = &cobra.Command{ Header: []string{"ID", "ProjectName", "GitURL", "Branches", "PullRequests", "ProductionRoute", "DevEnvironments", "DevEnvLimit", "ProductionEnv", "RouterPattern", "AutoIdle", "FactsUI", "ProblemsUI", "DeploymentsDisabled"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -163,7 +165,8 @@ This returns information about a deployment, the logs of this build can also be }, }, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } dataMain := output.Table{ @@ -188,7 +191,8 @@ This returns information about a deployment, the logs of this build can also be }, }, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -244,7 +248,8 @@ var getEnvironmentCmd = &cobra.Command{ Header: []string{"ID", "EnvironmentName", "EnvironmentType", "DeployType", "Created", "OpenshiftProjectName", "Route", "Routes", "AutoIdle", "DeployTitle", "DeployBaseRef", "DeployHeadRef"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -294,14 +299,16 @@ var getProjectKeyCmd = &cobra.Command{ if len(dataMain.Data) == 0 { outputOptions.Error = fmt.Sprintf("No project-key for project '%s'", cmdProjectName) - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } if projectKey.PrivateKey != "" { dataMain.Header = append(dataMain.Header, "PrivateKey") } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -371,7 +378,8 @@ var getOrganizationCmd = &cobra.Command{ Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/groups.go b/cmd/groups.go index b1ac7c39..a337a9cc 100644 --- a/cmd/groups.go +++ b/cmd/groups.go @@ -89,7 +89,8 @@ var addGroupCmd = &cobra.Command{ if organizationName != "" { resultData.ResultData["Organization"] = organizationName } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -162,7 +163,8 @@ var addUserToGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -224,7 +226,8 @@ var addProjectToGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -280,7 +283,8 @@ var deleteUserFromGroupCmd = &cobra.Command{ "id": result.ID, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -345,7 +349,8 @@ var deleteProjectFromGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -384,7 +389,8 @@ var deleteGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/list.go b/cmd/list.go index cbfbebe2..72f4f9d8 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -77,8 +77,8 @@ var listProjectsCmd = &cobra.Command{ Header: []string{"ID", "ProjectName", "GitUrl", "ProductionEnvironment", "DevEnvironments"}, Data: data, } - - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -127,7 +127,7 @@ var listDeployTargetsCmd = &cobra.Command{ }) } outputOptions.MultiLine = true - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -145,6 +145,7 @@ var listDeployTargetsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -189,7 +190,8 @@ var listGroupsCmd = &cobra.Command{ Header: []string{"ID", "Name"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -263,7 +265,8 @@ var listGroupProjectsCmd = &cobra.Command{ } else { outputOptions.Error = "There are no projects in any groups\n" } - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -274,7 +277,8 @@ var listGroupProjectsCmd = &cobra.Command{ if listAllProjects { dataMain.Header = append(dataMain.Header, "GroupName") } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -310,7 +314,8 @@ var listEnvironmentsCmd = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -334,7 +339,8 @@ var listEnvironmentsCmd = &cobra.Command{ Header: []string{"ID", "Name", "DeployType", "Environment", "Namespace", "Route", "DeployTarget"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -409,13 +415,15 @@ var listVariablesCmd = &cobra.Command{ } else { outputOptions.Error = fmt.Sprintf("There are no variables for project '%s'\n", cmdProjectName) } - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: header, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -470,14 +478,16 @@ var listDeploymentsCmd = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } dataMain := output.Table{ Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -533,14 +543,16 @@ var listTasksCmd = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } dataMain := output.Table{ Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed", "Service"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -608,7 +620,8 @@ Without a group name, this query may time out in large Lagoon instalschema.`, Header: []string{"ID", "GroupName", "Email", "Role"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -659,7 +672,8 @@ This query can take a long time to run if there are a lot of users.`, Header: []string{"ID", "Email", "FirstName", "LastName", "Comment"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -709,7 +723,8 @@ var listUsersGroupsCmd = &cobra.Command{ Header: []string{"ID", "Email", "GroupName", "GroupRole"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -759,14 +774,16 @@ var listInvokableTasks = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } dataMain := output.Table{ Header: []string{"Task Name", "Description"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -811,7 +828,8 @@ var listProjectGroupsCmd = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -831,7 +849,8 @@ var listProjectGroupsCmd = &cobra.Command{ Header: []string{"Group ID", "Group Name", "Organization"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -879,7 +898,8 @@ var listOrganizationProjectsCmd = &cobra.Command{ 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -895,7 +915,8 @@ var listOrganizationProjectsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Group Count"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -942,7 +963,8 @@ var listOrganizationGroupsCmd = &cobra.Command{ } 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -959,7 +981,8 @@ var listOrganizationGroupsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Type", "Member Count"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -1002,7 +1025,8 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ } 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) + r := output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil } @@ -1022,7 +1046,8 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Router Pattern", "Cloud Region", "Cloud Provider", "SSH Host", "SSH Port"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -1082,7 +1107,8 @@ var ListOrganizationUsersCmd = &cobra.Command{ Header: []string{"ID", "Email", "First Name", "LastName", "Comment", "Owner"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -1131,7 +1157,8 @@ var listOrganizationsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Description", "Project Quota", "Group Quota", "Notification Quota", "Environment Quota", "Route Quota"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/notificationsemail.go b/cmd/notificationsemail.go index bdd62a1a..13d037ac 100644 --- a/cmd/notificationsemail.go +++ b/cmd/notificationsemail.go @@ -78,7 +78,7 @@ It does not configure a project to send notifications to email though, you need notificationData = append(notificationData, "-") } data = append(data, notificationData) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -87,6 +87,7 @@ It does not configure a project to send notifications to email though, you need }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -135,7 +136,8 @@ This command is used to add an existing email notification in Lagoon to a projec resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -185,13 +187,14 @@ var listProjectEmailsCmd = &cobra.Command{ }) } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "EmailAddress", }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -233,7 +236,7 @@ var listAllEmailsCmd = &cobra.Command{ } } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Project", "Name", @@ -241,6 +244,7 @@ var listAllEmailsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -285,7 +289,8 @@ var deleteProjectEmailNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -326,7 +331,8 @@ var deleteEmailNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -392,7 +398,7 @@ var updateEmailNotificationCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", result.EmailAddress)), }, } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -400,6 +406,7 @@ var updateEmailNotificationCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/notificationsrocketchat.go b/cmd/notificationsrocketchat.go index f1130028..5d507802 100644 --- a/cmd/notificationsrocketchat.go +++ b/cmd/notificationsrocketchat.go @@ -85,7 +85,7 @@ It does not configure a project to send notifications to RocketChat though, you notificationData = append(notificationData, "-") } data = append(data, notificationData) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -95,6 +95,7 @@ It does not configure a project to send notifications to RocketChat though, you }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -144,7 +145,8 @@ This command is used to add an existing RocketChat notification in Lagoon to a p resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -195,7 +197,7 @@ var listProjectRocketChatsCmd = &cobra.Command{ }) } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "Webhook", @@ -203,6 +205,7 @@ var listProjectRocketChatsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -245,7 +248,7 @@ var listAllRocketChatsCmd = &cobra.Command{ } } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Project", "Name", @@ -254,6 +257,7 @@ var listAllRocketChatsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -298,7 +302,8 @@ var deleteProjectRocketChatNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -339,7 +344,8 @@ var deleteRocketChatNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -411,7 +417,7 @@ var updateRocketChatNotificationCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", result.Channel)), }, } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -420,6 +426,7 @@ var updateRocketChatNotificationCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/notificationsslack.go b/cmd/notificationsslack.go index 7032f3a2..7113d32e 100644 --- a/cmd/notificationsslack.go +++ b/cmd/notificationsslack.go @@ -85,7 +85,7 @@ It does not configure a project to send notifications to Slack though, you need notificationData = append(notificationData, "-") } data = append(data, notificationData) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -95,6 +95,7 @@ It does not configure a project to send notifications to Slack though, you need }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -142,7 +143,8 @@ This command is used to add an existing Slack notification in Lagoon to a projec resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -193,7 +195,7 @@ var listProjectSlacksCmd = &cobra.Command{ }) } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "Webhook", @@ -201,6 +203,7 @@ var listProjectSlacksCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -243,7 +246,7 @@ var listAllSlacksCmd = &cobra.Command{ } } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Project", "Name", @@ -252,6 +255,7 @@ var listAllSlacksCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -296,7 +300,8 @@ var deleteProjectSlackNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -337,7 +342,8 @@ var deleteSlackNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -409,7 +415,7 @@ var updateSlackNotificationCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", result.Channel)), }, } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -418,6 +424,7 @@ var updateSlackNotificationCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/notificationsteams.go b/cmd/notificationsteams.go index d267fb66..49cb0ef5 100644 --- a/cmd/notificationsteams.go +++ b/cmd/notificationsteams.go @@ -79,7 +79,7 @@ It does not configure a project to send notifications to Microsoft Teams though, notificationData = append(notificationData, "-") } data = append(data, notificationData) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -88,6 +88,7 @@ It does not configure a project to send notifications to Microsoft Teams though, }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -135,7 +136,8 @@ This command is used to add an existing Microsoft Teams notification in Lagoon t resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -185,13 +187,14 @@ var listProjectMicrosoftTeamsCmd = &cobra.Command{ }) } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "Webhook", }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -233,7 +236,7 @@ var listAllMicrosoftTeamsCmd = &cobra.Command{ } } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Project", "Name", @@ -241,6 +244,7 @@ var listAllMicrosoftTeamsCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -285,7 +289,8 @@ var deleteProjectMicrosoftTeamsNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -326,7 +331,8 @@ var deleteMicrosoftTeamsNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -392,7 +398,7 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", result.Webhook)), }, } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -400,6 +406,7 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/notificationswebhook.go b/cmd/notificationswebhook.go index 58eee15a..04125a0b 100644 --- a/cmd/notificationswebhook.go +++ b/cmd/notificationswebhook.go @@ -79,7 +79,7 @@ It does not configure a project to send notifications to webhook though, you nee notificationData = append(notificationData, "-") } data = append(data, notificationData) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -88,6 +88,7 @@ It does not configure a project to send notifications to webhook though, you nee }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -135,7 +136,8 @@ This command is used to add an existing webhook notification in Lagoon to a proj resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -185,13 +187,14 @@ var listProjectWebhooksCmd = &cobra.Command{ }) } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Name", "Webhook", }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -233,7 +236,7 @@ var listAllWebhooksCmd = &cobra.Command{ } } } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "Project", "Name", @@ -241,6 +244,7 @@ var listAllWebhooksCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -285,7 +289,8 @@ var deleteProjectWebhookNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -326,7 +331,8 @@ var deleteWebhookNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -392,7 +398,7 @@ var updateWebhookNotificationCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", result.Webhook)), }, } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -400,6 +406,7 @@ var updateWebhookNotificationCmd = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/organization.go b/cmd/organization.go index 1685a2b9..5ef92789 100644 --- a/cmd/organization.go +++ b/cmd/organization.go @@ -90,7 +90,8 @@ var addOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -139,7 +140,8 @@ var deleteOrganizationCmd = &cobra.Command{ resultData := output.Result{ Result: organization.Name, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -229,7 +231,8 @@ var updateOrganizationCmd = &cobra.Command{ "Organization Name": result.Name, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/project.go b/cmd/project.go index d4ef7079..04340f4b 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -50,7 +50,8 @@ var deleteProjectCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -203,7 +204,8 @@ var addProjectCmd = &cobra.Command{ if organizationName != "" { resultData.ResultData["Organization"] = organizationName } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -391,7 +393,8 @@ var updateProjectCmd = &cobra.Command{ "Project Name": projectUpdate.Name, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -460,10 +463,11 @@ var listProjectByMetadata = &cobra.Command{ if showMetadata { header = append(header, "Metadata") } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: header, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -510,10 +514,11 @@ var getProjectMetadata = &cobra.Command{ "Key", "Value", } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: header, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -565,7 +570,7 @@ var updateProjectMetadata = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", projectResult.Name)), returnNonEmptyString(fmt.Sprintf("%v", string(metaData))), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -573,6 +578,7 @@ var updateProjectMetadata = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -621,7 +627,7 @@ var deleteProjectMetadataByKey = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", projectResult.Name)), returnNonEmptyString(fmt.Sprintf("%v", string(metaData))), }) - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Name", @@ -629,6 +635,7 @@ var deleteProjectMetadataByKey = &cobra.Command{ }, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -694,7 +701,8 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/tasks.go b/cmd/tasks.go index 3b28c0e4..02272424 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -79,7 +79,8 @@ var getTaskByID = &cobra.Command{ dataMain.Header = append(dataMain.Header, "Logs") dataMain.Data[0] = append(dataMain.Data[0], returnNonEmptyString(result.Logs)) } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -181,7 +182,8 @@ var runDrushArchiveDump = &cobra.Command{ Result: "success", ResultData: resultMap["taskDrushArchiveDump"].(map[string]interface{}), } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { return fmt.Errorf("unable to determine status of task") } @@ -249,7 +251,8 @@ var runDrushSQLDump = &cobra.Command{ Result: "success", ResultData: resultMap["taskDrushSqlDump"].(map[string]interface{}), } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { return fmt.Errorf("unable to determine status of task") } @@ -317,7 +320,8 @@ var runDrushCacheClear = &cobra.Command{ Result: "success", ResultData: resultMap["taskDrushCacheClear"].(map[string]interface{}), } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { return fmt.Errorf("unable to determine status of task") } @@ -388,7 +392,8 @@ Direct: "status": taskResult.Status, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -489,7 +494,8 @@ Path: "id": taskResult.ID, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -549,7 +555,8 @@ var uploadFilesToTask = &cobra.Command{ }, }, } - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } diff --git a/cmd/users.go b/cmd/users.go index 40d04c39..5ea7909e 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -121,7 +121,8 @@ var addUserCmd = &cobra.Command{ "id": user.ID, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -199,7 +200,8 @@ Add key by defining key value, but not specifying a key name (will default to tr "ID": result.ID, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -241,7 +243,8 @@ var deleteSSHKeyCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -287,7 +290,8 @@ var deleteUserCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -362,7 +366,8 @@ var updateUserCmd = &cobra.Command{ "ID": user.ID, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -423,7 +428,8 @@ var getUserKeysCmd = &cobra.Command{ } outputOptions.MultiLine = true - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -492,7 +498,8 @@ var getAllUserKeysCmd = &cobra.Command{ Data: data, } outputOptions.MultiLine = true - output.RenderOutput(dataMain, outputOptions) + r := output.RenderOutput(dataMain, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -563,7 +570,8 @@ var addAdministratorToOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) return nil }, } @@ -635,7 +643,8 @@ var removeAdministratorFromOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -682,7 +691,8 @@ var resetPasswordCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/variables.go b/cmd/variables.go index 88e6bc5a..c6a210ea 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -85,10 +85,11 @@ var addVariableCmd = &cobra.Command{ header = append(header, "Scope") header = append(header, "Name") header = append(header, "Value") - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: header, Data: data, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { output.RenderInfo(fmt.Sprintf("variable %s remained unchanged", varName), outputOptions) } @@ -142,7 +143,8 @@ var deleteVariableCmd = &cobra.Command{ resultData := output.Result{ Result: deleteResult.DeleteEnvVar, } - output.RenderResult(resultData, outputOptions) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/whoami.go b/cmd/whoami.go index d8193548..ff0387b8 100644 --- a/cmd/whoami.go +++ b/cmd/whoami.go @@ -86,12 +86,13 @@ This is useful if you have multiple keys or accounts in multiple lagoons and nee } keys = append(keys, keyData) } - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: header, Data: keys, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } else { - output.RenderOutput(output.Table{ + r := output.RenderOutput(output.Table{ Header: []string{ "ID", "Email", @@ -109,6 +110,7 @@ This is useful if you have multiple keys or accounts in multiple lagoons and nee }, }, }, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil diff --git a/pkg/output/main.go b/pkg/output/main.go index e40e24f0..35388a33 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -1,6 +1,7 @@ package output import ( + "bytes" "encoding/json" "fmt" "os" @@ -39,7 +40,7 @@ type Result struct { } // RenderJSON . -func RenderJSON(data interface{}, opts Options) { +func RenderJSON(data interface{}, opts Options) string { var jsonBytes []byte var err error if opts.Pretty { @@ -53,7 +54,7 @@ func RenderJSON(data interface{}, opts Options) { panic(err) } } - fmt.Println(string(jsonBytes)) + return string(jsonBytes) } // RenderError . @@ -64,8 +65,7 @@ func RenderError(errorMsg string, opts Options) { } RenderJSON(jsonData, opts) } else { - //fmt.Println(fmt.Sprintf("Error: %s", aurora.Yellow(trimQuotes(errorMsg)))) - fmt.Println("Error:", trimQuotes(errorMsg)) + os.Stderr.WriteString(fmt.Sprintf("Error: %s", trimQuotes(errorMsg))) } } @@ -77,38 +77,40 @@ func RenderInfo(infoMsg string, opts Options) { } RenderJSON(jsonData, opts) } else { - fmt.Println("Info:", trimQuotes(infoMsg)) + os.Stderr.WriteString(fmt.Sprintf("Info: %s", trimQuotes(infoMsg))) } } // RenderResult . -func RenderResult(result Result, opts Options) { +func RenderResult(result Result, opts Options) string { + var out bytes.Buffer if opts.JSON { - RenderJSON(result, opts) + return RenderJSON(result, opts) } else { if trimQuotes(result.Result) == "success" { - fmt.Printf("Result: %s\n", aurora.Green(trimQuotes(result.Result))) + out.WriteString(fmt.Sprintf("Result: %s\n", aurora.Green(trimQuotes(result.Result)))) if len(result.ResultData) != 0 { for k, v := range result.ResultData { - fmt.Printf("%s: %v\n", k, v) + out.WriteString(fmt.Sprintf("%s: %v\n", k, v)) } } } else { fmt.Printf("Result: %s\n", aurora.Yellow(trimQuotes(result.Result))) if len(result.ResultData) != 0 { for k, v := range result.ResultData { - fmt.Printf("%s: %v\n", k, v) + out.WriteString(fmt.Sprintf("%s: %v\n", k, v)) } } } } - + return out.String() } // RenderOutput . -func RenderOutput(data Table, opts Options) { +func RenderOutput(data Table, opts Options) string { + var out bytes.Buffer if opts.Debug { - fmt.Printf("%s\n", aurora.Yellow("Final result:")) + out.WriteString(fmt.Sprintf("%s\n", aurora.Yellow("Final result:"))) } if opts.JSON { // really basic tabledata to json implementation @@ -124,7 +126,7 @@ func RenderOutput(data Table, opts Options) { returnedData := map[string]interface{}{ "data": rawData, } - RenderJSON(returnedData, opts) + return RenderJSON(returnedData, opts) } else { // otherwise render a table if opts.Error != "" { @@ -139,7 +141,7 @@ func RenderOutput(data Table, opts Options) { } t.AppendHeader(hRow) } - t.SetOutputMirror(os.Stdout) + t.SetOutputMirror(&out) for _, rowData := range data.Data { var dRow table.Row for _, k := range rowData { @@ -164,9 +166,10 @@ func RenderOutput(data Table, opts Options) { if opts.CSV { t.RenderCSV() - return + return out.String() } t.Render() + return out.String() } } From 7fd9faf96415750f4f29b9d28b59590b2e7665f6 Mon Sep 17 00:00:00 2001 From: cgoodwin90 Date: Fri, 21 Jun 2024 12:07:44 +1000 Subject: [PATCH 2/3] Initial Commit --- Makefile | 29 +++- cmd/deploy.go | 13 +- cmd/deploy_test.go | 104 ++++++++++++++ cmd/deploytarget.go | 10 +- cmd/deploytarget_test.go | 82 +++++++++++ cmd/deploytargetconfig.go | 15 +- cmd/deploytargetconfig_test.go | 94 ++++++++++++ cmd/environment.go | 6 +- cmd/environment_test.go | 108 ++++++++++++++ cmd/get.go | 16 +-- cmd/get_test.go | 94 ++++++++++++ cmd/groups.go | 16 +-- cmd/groups_test.go | 127 ++++++++++++++++ cmd/list.go | 56 ++++---- cmd/list_test.go | 215 ++++++++++++++++++++++++++++ cmd/notificationsemail.go | 14 +- cmd/notificationsemail_test.go | 127 ++++++++++++++++ cmd/notificationsrocketchat.go | 14 +- cmd/notificationsrocketchat_test.go | 127 ++++++++++++++++ cmd/notificationsslack.go | 14 +- cmd/notificationsslack_test.go | 127 ++++++++++++++++ cmd/notificationsteams.go | 14 +- cmd/notificationsteams_test.go | 127 ++++++++++++++++ cmd/notificationswebhook.go | 14 +- cmd/notificationswebhook_test.go | 127 ++++++++++++++++ cmd/organization.go | 6 +- cmd/organization_test.go | 81 +++++++++++ cmd/project.go | 18 +-- cmd/project_test.go | 106 ++++++++++++++ cmd/shared.go | 20 +++ cmd/tasks_test.go | 64 +++++++++ cmd/users_test.go | 140 ++++++++++++++++++ cmd/variables.go | 6 +- cmd/variables_test.go | 96 +++++++++++++ pkg/output/main.go | 52 +++++-- test/Makefile | 34 +++++ test/docker-compose.yaml | 79 ++++++++++ test/keycloak/configure-keycloak.sh | 52 +++++++ 38 files changed, 2319 insertions(+), 125 deletions(-) create mode 100644 cmd/deploy_test.go create mode 100644 cmd/deploytarget_test.go create mode 100644 cmd/deploytargetconfig_test.go create mode 100644 cmd/environment_test.go create mode 100644 cmd/get_test.go create mode 100644 cmd/groups_test.go create mode 100644 cmd/list_test.go create mode 100644 cmd/notificationsemail_test.go create mode 100644 cmd/notificationsrocketchat_test.go create mode 100644 cmd/notificationsslack_test.go create mode 100644 cmd/notificationsteams_test.go create mode 100644 cmd/notificationswebhook_test.go create mode 100644 cmd/organization_test.go create mode 100644 cmd/project_test.go create mode 100644 cmd/tasks_test.go create mode 100644 cmd/users_test.go create mode 100644 cmd/variables_test.go create mode 100644 test/Makefile create mode 100644 test/docker-compose.yaml create mode 100755 test/keycloak/configure-keycloak.sh diff --git a/Makefile b/Makefile index cdc78c0a..95e9c5be 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ all-docker-darwin: deps-docker test-docker build-docker-darwin gen: deps GO111MODULE=on $(GOCMD) generate ./... -deps: +deps: GO111MODULE=on ${GOCMD} get -v test: gen GO111MODULE=on $(GOCMD) fmt ./... @@ -40,7 +40,7 @@ build-darwin: test GO111MODULE=on CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GOCMD) build -ldflags '${LDFLAGS} -X "${PKG}/cmd.lagoonCLIBuildGoVersion=${GO_VER}"' -o builds/lagoon-cli-${VERSION}-darwin-amd64 -v docs: test - LAGOON_GEN_DOCS=true GO111MODULE=on $(GOCMD) run main.go --docs + LAGOON_GEN_DOCS=true GO111MODULE=on $(GOCMD) run main.go --docs tidy: GO111MODULE=on $(GOCMD) mod tidy @@ -96,20 +96,39 @@ install-linux: install-darwin: cp builds/lagoon-cli-${VERSION}-darwin-amd64 ${ARTIFACT_DESTINATION}/lagoon -release-patch: +release-patch: $(eval VERSION=$(shell ${PWD}/increment_ver.sh -p $(shell git describe --abbrev=0 --tags))) git tag $(VERSION) mkdocs gh-deploy git push $(GIT_ORIGIN) main --tags -release-minor: +release-minor: $(eval VERSION=$(shell ${PWD}/increment_ver.sh -m $(shell git describe --abbrev=0 --tags))) git tag $(VERSION) mkdocs gh-deploy git push $(GIT_ORIGIN) main --tags -release-major: +release-major: $(eval VERSION=$(shell ${PWD}/increment_ver.sh -M $(shell git describe --abbrev=0 --tags))) git tag $(VERSION) mkdocs gh-deploy git push $(GIT_ORIGIN) main --tags + +# upstream +CI_BUILD_TAG ?= lagoon-cli +CORE_REPO=https://github.com/uselagoon/lagoon.git +CORE_TREEISH=main + +.PHONY: test-with-api +test-with-api: + export LAGOON_CORE=$$(mktemp -d ./lagoon-core.XXX) \ + && git clone $(CORE_REPO) "$$LAGOON_CORE" \ + && cd "$$LAGOON_CORE" \ + && git checkout $(CORE_TREEISH) \ + && IMAGE_REPO=uselagoon docker compose -p $(CI_BUILD_TAG) --compatibility up -d api api-db actions-handler local-api-data-watcher-pusher keycloak keycloak-db broker api-redis logs2notifications local-minio mailhog \ + && $(MAKE) CI_BUILD_TAG=$(CI_BUILD_TAG) wait-for-keycloak \ + && cd .. \ + && echo "DO TESTS STUFF HERE" \ + && $(MAKE) test \ + && cd "$$LAGOON_CORE" \ + && $(MAKE) CI_BUILD_TAG=$(CI_BUILD_TAG) down diff --git a/cmd/deploy.go b/cmd/deploy.go index c8b771e4..4f5d30a0 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -3,6 +3,7 @@ package cmd import ( "context" "fmt" + "github.com/uselagoon/lagoon-cli/pkg/output" "strconv" lclient "github.com/uselagoon/machinery/api/lagoon/client" @@ -80,7 +81,8 @@ use 'lagoon deploy latest' instead`, if err != nil { return err } - fmt.Println(result.DeployEnvironmentBranch) + resultData := output.Result{Result: result.DeployEnvironmentBranch} + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -143,7 +145,8 @@ var deployPromoteCmd = &cobra.Command{ if err != nil { return err } - fmt.Println(result.DeployEnvironmentPromote) + resultData := output.Result{Result: result.DeployEnvironmentPromote} + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -204,7 +207,8 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo if err != nil { return err } - fmt.Println(result.DeployEnvironmentLatest) + resultData := output.Result{Result: result.DeployEnvironmentLatest} + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -291,7 +295,8 @@ This pullrequest may not already exist as an environment in lagoon.`, if err != nil { return err } - fmt.Println(result.DeployEnvironmentPullrequest) + resultData := output.Result{Result: result.DeployEnvironmentPullrequest} + output.RenderResult(resultData, outputOptions, cmd) } return nil }, diff --git a/cmd/deploy_test.go b/cmd/deploy_test.go new file mode 100644 index 00000000..a066f38c --- /dev/null +++ b/cmd/deploy_test.go @@ -0,0 +1,104 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestDeployCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Deploy Branch", + cmdArgs: []string{"deploy", "branch", "--project=lagoon-demo", "--branch=dev", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deployCmd) + deployCmd.AddCommand(deployBranchCmd) + AddGenericFlags(deployBranchCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Get Deployment", + cmdArgs: []string{"get", "deployment", "--project=lagoon-demo", "--environment=main", "--name=lagoon-build-def456", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getDeploymentByNameCmd) + AddGenericFlags(getDeploymentByNameCmd) + }, + expectOut: []string{"lagoon-build-def456", "85e36e3c-a755-11ed-abf6-df28d8a74109"}, + expectErr: false, + }, + { + name: "Deploy Promote", + cmdArgs: []string{"deploy", "promote", "--project=lagoon-demo-org", "--source=pr-15", "--destination=staging", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deployCmd) + deployCmd.AddCommand(deployPromoteCmd) + AddGenericFlags(deployPromoteCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Deploy Latest", + cmdArgs: []string{"deploy", "latest", "--project=lagoon-demo", "--environment=dev", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deployCmd) + deployCmd.AddCommand(deployLatestCmd) + AddGenericFlags(deployLatestCmd) + }, + expectOut: []string{"lagoon-build-"}, + expectErr: false, + }, + { + name: "Deploy Pullrequest", + cmdArgs: []string{"deploy", "pullrequest", "--project=lagoon-demo-org", "--title=pr-15", "--number=15", "--baseBranchName=pr-15", "--baseBranchRef=branchRef", "--headBranchName=branchName", "--headBranchRef=headBranchRef", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deployCmd) + deployCmd.AddCommand(deployPullrequestCmd) + AddGenericFlags(deployPullrequestCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/deploytarget.go b/cmd/deploytarget.go index b4f9d27e..c1d3269d 100644 --- a/cmd/deploytarget.go +++ b/cmd/deploytarget.go @@ -137,7 +137,7 @@ var addDeployTargetCmd = &cobra.Command{ "MonitoringConfig", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -269,7 +269,7 @@ var updateDeployTargetCmd = &cobra.Command{ "MonitoringConfig", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -319,7 +319,7 @@ var deleteDeployTargetCmd = &cobra.Command{ resultData := output.Result{ Result: deleteDeployTargetResponse.DeleteDeployTarget, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -383,7 +383,7 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ "Organization Name": deployTargetResponse.Name, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -447,7 +447,7 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, diff --git a/cmd/deploytarget_test.go b/cmd/deploytarget_test.go new file mode 100644 index 00000000..7d61d597 --- /dev/null +++ b/cmd/deploytarget_test.go @@ -0,0 +1,82 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestDeployTargetCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Deploytarget", + cmdArgs: []string{"add", "deploytarget", "--name=test-deploytarget", "--console-url=https://localhost:3000/", "--token=abcd1234", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addDeployTargetCmd) + AddGenericFlags(addDeployTargetCmd) + }, + expectOut: []string{"test-deploytarget", "https://localhost:3000/", "abcd1234"}, + expectErr: false, + }, + { + name: "Update Deploytarget", + cmdArgs: []string{"update", "deploytarget", "--id=4", "--friendly-name=ui-kubernetes-deploytarget", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateDeployTargetCmd) + AddGenericFlags(updateDeployTargetCmd) + }, + expectOut: []string{"ui-kubernetes", "ui-kubernetes-deploytarget"}, + expectErr: false, + }, + { + name: "Delete Deploytarget", + cmdArgs: []string{"delete", "deploytarget", "--name=test-deploytarget", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteDeployTargetCmd) + AddGenericFlags(deleteDeployTargetCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/deploytargetconfig.go b/cmd/deploytargetconfig.go index cb4465f3..4ccc852e 100644 --- a/cmd/deploytargetconfig.go +++ b/cmd/deploytargetconfig.go @@ -102,7 +102,7 @@ var addDeployTargetConfigCmd = &cobra.Command{ "CloudRegion", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -196,7 +196,7 @@ var updateDeployTargetConfigCmd = &cobra.Command{ "CloudRegion", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -238,7 +238,7 @@ var deleteDeployTargetConfigCmd = &cobra.Command{ } if project.Name == "" { outputOptions.Error = fmt.Sprintf("No details for project '%s'", cmdProjectName) - output.RenderError(outputOptions.Error, outputOptions) + output.RenderError(outputOptions.Error, outputOptions, cmd) return nil } @@ -247,7 +247,10 @@ var deleteDeployTargetConfigCmd = &cobra.Command{ if err != nil { return err } - fmt.Println(result.DeleteDeployTargetConfig) + resultData := output.Result{ + Result: result.DeleteDeployTargetConfig, + } + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -286,7 +289,7 @@ var listDeployTargetConfigsCmd = &cobra.Command{ } if project.Name == "" { outputOptions.Error = fmt.Sprintf("No details for project '%s'", cmdProjectName) - output.RenderError(outputOptions.Error, outputOptions) + output.RenderError(outputOptions.Error, outputOptions, cmd) return nil } deployTargetConfigs, err := lagoon.GetDeployTargetConfigs(context.TODO(), int(project.ID), lc) @@ -318,7 +321,7 @@ var listDeployTargetConfigsCmd = &cobra.Command{ "CloudRegion", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } diff --git a/cmd/deploytargetconfig_test.go b/cmd/deploytargetconfig_test.go new file mode 100644 index 00000000..fb5619e9 --- /dev/null +++ b/cmd/deploytargetconfig_test.go @@ -0,0 +1,94 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestDeployTargetConfigCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Deploytarget-config", + cmdArgs: []string{"add", "deploytarget-config", "--project=lagoon-demo", "--deploytarget=2001", "--pullrequests=true", "--branches=false", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addDeployTargetConfigCmd) + AddGenericFlags(addDeployTargetConfigCmd) + }, + expectOut: []string{"true", "false", "ci-local-control-k8s"}, + expectErr: false, + }, + // TODO: Seed deploytarget-config data + { + name: "List Deploytarget-configs", + cmdArgs: []string{"list", "deploytarget-configs", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listDeployTargetConfigsCmd) + AddGenericFlags(listDeployTargetConfigsCmd) + }, + expectOut: []string{"true", "false", "ci-local-control-k8s"}, + expectErr: false, + }, + { + name: "Update Deploytarget-config", + cmdArgs: []string{"update", "deploytarget-config", "--id=1", "--weight=2", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateDeployTargetConfigCmd) + AddGenericFlags(updateDeployTargetConfigCmd) + }, + expectOut: []string{"2", "ci-local-control-k8s"}, + expectErr: false, + }, + { + name: "Delete Deploytarget-config", + cmdArgs: []string{"delete", "deploytarget-config", "--project=lagoon-demo", "--id=1", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteDeployTargetConfigCmd) + AddGenericFlags(deleteDeployTargetConfigCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/environment.go b/cmd/environment.go index 7875b94f..ef4688c3 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -50,7 +50,7 @@ var deleteEnvCmd = &cobra.Command{ resultData := output.Result{ Result: environment.DeleteEnvironment, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -172,7 +172,7 @@ var updateEnvironmentCmd = &cobra.Command{ "Environment Name": result.Name, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -242,7 +242,7 @@ var listBackupsCmd = &cobra.Command{ "RestoreStatus", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } diff --git a/cmd/environment_test.go b/cmd/environment_test.go new file mode 100644 index 00000000..d93c2e33 --- /dev/null +++ b/cmd/environment_test.go @@ -0,0 +1,108 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestEnvironmentCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + { + name: "List Backups", + cmdArgs: []string{"list", "backups", "--project=lagoon-demo", "--environment=main", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listBackupsCmd) + AddGenericFlags(listBackupsCmd) + }, + expectOut: []string{"e2e1d31b4a7dfc1687f469b6673f6bf2c0aabee0cc6b3f1bdbde710a9bc6280f", "files", "e2e1d31b4a7dfc1687f469b6673f6bf2c0aabee0cc6b3f1bdbde710a9bc6280d", "mariadb"}, + expectErr: false, + }, + { + name: "Get Backup - Error: no download file found", + cmdArgs: []string{"get", "backup", "--project=lagoon-demo", "--environment=main", "--backup-id=e260f07c374e4a3319c5d46e688dab6f1eb23c3e61c166a37609d55762d2ee0b", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getBackupCmd) + AddGenericFlags(getBackupCmd) + }, + expectOut: []string{""}, + expectErr: true, + expectedErrString: "no download file found, status of backups restoration is failed", + }, + { + name: "Get Backup - Error: backup has not been restored", + cmdArgs: []string{"get", "backup", "--project=lagoon-demo", "--environment=main", "--backup-id=bf072a09e17726da54adc79936ec8745521993599d41211dfc9466dfd5bc32a5", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getBackupCmd) + AddGenericFlags(getBackupCmd) + }, + expectOut: []string{""}, + expectErr: true, + expectedErrString: "backup has not been restored", + }, + // TODO: Seed backup data to test success path (getBackup) + { + name: "Update Environment", + cmdArgs: []string{"update", "environment", "--project=lagoon-demo", "--environment=pr-175", "--auto-idle=0", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateEnvironmentCmd) + AddGenericFlags(updateEnvironmentCmd) + }, + expectOut: []string{"success", "pr-175"}, + expectErr: false, + }, + { + name: "Delete Environment", + cmdArgs: []string{"delete", "environment", "--project=lagoon-demo", "--environment=pr-175", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteEnvCmd) + AddGenericFlags(deleteEnvCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/get.go b/cmd/get.go index bcccbe8c..5c1a09a3 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -60,7 +60,7 @@ var getProjectCmd = &cobra.Command{ if project.Name == "" { outputOptions.Error = fmt.Sprintf("No details for project '%s'\n", cmdProjectName) - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -112,7 +112,7 @@ var getProjectCmd = &cobra.Command{ Header: []string{"ID", "ProjectName", "GitURL", "Branches", "PullRequests", "ProductionRoute", "DevEnvironments", "DevEnvLimit", "ProductionEnv", "RouterPattern", "AutoIdle", "FactsUI", "ProblemsUI", "DeploymentsDisabled"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -163,7 +163,7 @@ This returns information about a deployment, the logs of this build can also be }, }, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil } dataMain := output.Table{ @@ -188,7 +188,7 @@ This returns information about a deployment, the logs of this build can also be }, }, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -244,7 +244,7 @@ var getEnvironmentCmd = &cobra.Command{ Header: []string{"ID", "EnvironmentName", "EnvironmentType", "DeployType", "Created", "OpenshiftProjectName", "Route", "Routes", "AutoIdle", "DeployTitle", "DeployBaseRef", "DeployHeadRef"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -294,14 +294,14 @@ var getProjectKeyCmd = &cobra.Command{ if len(dataMain.Data) == 0 { outputOptions.Error = fmt.Sprintf("No project-key for project '%s'", cmdProjectName) - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } if projectKey.PrivateKey != "" { dataMain.Header = append(dataMain.Header, "PrivateKey") } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -371,7 +371,7 @@ var getOrganizationCmd = &cobra.Command{ Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } diff --git a/cmd/get_test.go b/cmd/get_test.go new file mode 100644 index 00000000..fad31c27 --- /dev/null +++ b/cmd/get_test.go @@ -0,0 +1,94 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestGetCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Get Organization", + cmdArgs: []string{"get", "organization", "--organization-name=lagoon-demo-organization", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getOrganizationCmd) + AddGenericFlags(getOrganizationCmd) + }, + expectOut: []string{"lagoon-demo-organization", "An organization for testing"}, + expectErr: false, + }, + { + name: "Get Project", + cmdArgs: []string{"get", "project", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getProjectCmd) + AddGenericFlags(getProjectCmd) + }, + expectOut: []string{"lagoon-demo", "ssh://git@example.com/lagoon-demo.git"}, + expectErr: false, + }, + { + name: "Get Environment", + cmdArgs: []string{"get", "environment", "--project=lagoon-demo", "--environment=staging", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getEnvironmentCmd) + AddGenericFlags(getEnvironmentCmd) + }, + expectOut: []string{"staging", "development", "branch"}, + expectErr: false, + }, + // TODO: set static value for project-key in seed + { + name: "Get Project Key", + cmdArgs: []string{"get", "project-key", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getProjectKeyCmd) + AddGenericFlags(getProjectKeyCmd) + }, + expectOut: []string{"ssh-ed25519"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/groups.go b/cmd/groups.go index b1ac7c39..883fa221 100644 --- a/cmd/groups.go +++ b/cmd/groups.go @@ -89,7 +89,7 @@ var addGroupCmd = &cobra.Command{ if organizationName != "" { resultData.ResultData["Organization"] = organizationName } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -162,7 +162,7 @@ var addUserToGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -213,7 +213,7 @@ var addProjectToGroupCmd = &cobra.Command{ } if len(project.Name) == 0 { outputOptions.Error = fmt.Sprintf("Project '%s' not found", cmdProjectName) - output.RenderError(outputOptions.Error, outputOptions) + output.RenderError(outputOptions.Error, outputOptions, cmd) return nil } _, err = lagoon.AddProjectToGroup(context.TODO(), projectGroup, lc) @@ -224,7 +224,7 @@ var addProjectToGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -280,7 +280,7 @@ var deleteUserFromGroupCmd = &cobra.Command{ "id": result.ID, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -332,7 +332,7 @@ var deleteProjectFromGroupCmd = &cobra.Command{ } if len(project.Name) == 0 { outputOptions.Error = fmt.Sprintf("Project '%s' not found", cmdProjectName) - output.RenderError(outputOptions.Error, outputOptions) + output.RenderError(outputOptions.Error, outputOptions, cmd) return nil } @@ -345,7 +345,7 @@ var deleteProjectFromGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -384,7 +384,7 @@ var deleteGroupCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, diff --git a/cmd/groups_test.go b/cmd/groups_test.go new file mode 100644 index 00000000..d0a72597 --- /dev/null +++ b/cmd/groups_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestGroupCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + { + name: "Add Group", + cmdArgs: []string{"add", "group", "--name=test-group", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addGroupCmd) + AddGenericFlags(addGroupCmd) + }, + expectOut: []string{"success", "test-group"}, + expectErr: false, + }, + { + name: "Delete Group", + cmdArgs: []string{"delete", "group", "--name=test-group", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteGroupCmd) + AddGenericFlags(deleteGroupCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Add Group to Organization", + cmdArgs: []string{"add", "group", "--name=test-organization-group", "--organization-name=lagoon-demo-organization", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addGroupCmd) + AddGenericFlags(addGroupCmd) + }, + expectOut: []string{"success", "test-organization-group", "lagoon-demo-organization"}, + expectErr: false, + }, + { + name: "Add User to Group", + cmdArgs: []string{"add", "user-group", "--name=lagoon-demo-group", "--email=ci-customer-user-ecdsa@example.com", "--role=guest", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addUserToGroupCmd) + AddGenericFlags(addUserToGroupCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete User from Group", + cmdArgs: []string{"delete", "user-group", "--name=lagoon-demo-group", "--email=ci-customer-user-ecdsa@example.com", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteUserFromGroupCmd) + AddGenericFlags(deleteUserFromGroupCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Add Project to Group", + cmdArgs: []string{"add", "project-group", "--name=ci-group", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectToGroupCmd) + AddGenericFlags(addProjectToGroupCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete Project from Group", + cmdArgs: []string{"delete", "project-group", "--name=ci-group", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectFromGroupCmd) + AddGenericFlags(deleteProjectFromGroupCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/list.go b/cmd/list.go index cbfbebe2..d9230c41 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -78,7 +78,7 @@ var listProjectsCmd = &cobra.Command{ Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -144,7 +144,7 @@ var listDeployTargetsCmd = &cobra.Command{ "MonitoringConfig", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -189,7 +189,7 @@ var listGroupsCmd = &cobra.Command{ Header: []string{"ID", "Name"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -263,7 +263,7 @@ var listGroupProjectsCmd = &cobra.Command{ } else { outputOptions.Error = "There are no projects in any groups\n" } - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -274,7 +274,7 @@ var listGroupProjectsCmd = &cobra.Command{ if listAllProjects { dataMain.Header = append(dataMain.Header, "GroupName") } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -310,7 +310,7 @@ var listEnvironmentsCmd = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -334,7 +334,7 @@ var listEnvironmentsCmd = &cobra.Command{ Header: []string{"ID", "Name", "DeployType", "Environment", "Namespace", "Route", "DeployTarget"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -409,13 +409,13 @@ var listVariablesCmd = &cobra.Command{ } else { outputOptions.Error = fmt.Sprintf("There are no variables for project '%s'\n", cmdProjectName) } - output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } output.RenderOutput(output.Table{ Header: header, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -470,14 +470,14 @@ var listDeploymentsCmd = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } dataMain := output.Table{ Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -533,14 +533,14 @@ var listTasksCmd = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } dataMain := output.Table{ Header: []string{"ID", "RemoteID", "Name", "Status", "Created", "Started", "Completed", "Service"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -608,7 +608,7 @@ Without a group name, this query may time out in large Lagoon instalschema.`, Header: []string{"ID", "GroupName", "Email", "Role"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -659,7 +659,7 @@ This query can take a long time to run if there are a lot of users.`, Header: []string{"ID", "Email", "FirstName", "LastName", "Comment"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -709,7 +709,7 @@ var listUsersGroupsCmd = &cobra.Command{ Header: []string{"ID", "Email", "GroupName", "GroupRole"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -759,14 +759,14 @@ var listInvokableTasks = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } dataMain := output.Table{ Header: []string{"Task Name", "Description"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -811,7 +811,7 @@ var listProjectGroupsCmd = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -831,7 +831,7 @@ var listProjectGroupsCmd = &cobra.Command{ Header: []string{"Group ID", "Group Name", "Organization"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -879,7 +879,7 @@ var listOrganizationProjectsCmd = &cobra.Command{ 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -895,7 +895,7 @@ var listOrganizationProjectsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Group Count"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -942,7 +942,7 @@ var listOrganizationGroupsCmd = &cobra.Command{ } 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -959,7 +959,7 @@ var listOrganizationGroupsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Type", "Member Count"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -1002,7 +1002,7 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ } 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) + output.RenderOutput(output.Table{Data: []output.Data{[]string{}}}, outputOptions, cmd) return nil } @@ -1022,7 +1022,7 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Router Pattern", "Cloud Region", "Cloud Provider", "SSH Host", "SSH Port"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -1082,7 +1082,7 @@ var ListOrganizationUsersCmd = &cobra.Command{ Header: []string{"ID", "Email", "First Name", "LastName", "Comment", "Owner"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } @@ -1131,7 +1131,7 @@ var listOrganizationsCmd = &cobra.Command{ Header: []string{"ID", "Name", "Description", "Project Quota", "Group Quota", "Notification Quota", "Environment Quota", "Route Quota"}, Data: data, } - output.RenderOutput(dataMain, outputOptions) + output.RenderOutput(dataMain, outputOptions, cmd) return nil }, } diff --git a/cmd/list_test.go b/cmd/list_test.go new file mode 100644 index 00000000..24783813 --- /dev/null +++ b/cmd/list_test.go @@ -0,0 +1,215 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestListCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "List Projects", + cmdArgs: []string{"list", "projects", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectsCmd) + AddGenericFlags(listProjectsCmd) + }, + expectOut: []string{"lagoon-demo", "lagoon-demo-org"}, + expectErr: false, + }, + { + name: "List Deploy Targets", + cmdArgs: []string{"list", "deploytargets", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listDeployTargetsCmd) + AddGenericFlags(listDeployTargetsCmd) + }, + expectOut: []string{"ui-kubernetes", "ci-local-control-k8s"}, + expectErr: false, + }, + { + name: "List Groups", + cmdArgs: []string{"list", "groups", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listGroupsCmd) + AddGenericFlags(listGroupsCmd) + }, + expectOut: []string{"ci-group", "lagoon-demo-group", "lagoon-demo-organization-group", "project-lagoon-demo"}, + expectErr: false, + }, + { + name: "List Environments", + cmdArgs: []string{"list", "environments", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listEnvironmentsCmd) + AddGenericFlags(listEnvironmentsCmd) + }, + expectOut: []string{"main", "staging", "dev"}, + expectErr: false, + }, + { + name: "List Deployments", + cmdArgs: []string{"list", "deployments", "--project=lagoon-demo", "--environment=main", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listDeploymentsCmd) + AddGenericFlags(listDeploymentsCmd) + }, + expectOut: []string{"lagoon-build-7g8h9i", "lagoon-build-def456", "lagoon-build-123abc"}, + expectErr: false, + }, + { + name: "List Tasks", + cmdArgs: []string{"list", "tasks", "--project=lagoon-demo", "--environment=main", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listTasksCmd) + AddGenericFlags(listTasksCmd) + }, + expectOut: []string{"5b21aff1-689c-41b7-80d7-6de9f5bff1f3", "Developer task"}, + expectErr: false, + }, + { + name: "List Users - all groups", + cmdArgs: []string{"list", "group-users", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listUsersCmd) + AddGenericFlags(listUsersCmd) + }, + expectOut: []string{"ci-customer-user-rsa@example.com", "default-user@lagoon-demo"}, + expectErr: false, + }, + { + name: "List Users", + cmdArgs: []string{"list", "group-users", "--name=lagoon-demo-group", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listUsersCmd) + AddGenericFlags(listUsersCmd) + }, + expectOut: []string{"lagoon-demo-group", "guest@example.com"}, + expectErr: false, + }, + { + name: "List all users", + cmdArgs: []string{"list", "all-users", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllUsersCmd) + AddGenericFlags(listAllUsersCmd) + }, + expectOut: []string{"default-user@lagoon-demo", "ci-customer-user-rsa@example.com", "developer@example.com"}, + expectErr: false, + }, + { + name: "List group-projects", + cmdArgs: []string{"list", "group-projects", "--name=lagoon-demo-group", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listGroupProjectsCmd) + AddGenericFlags(listGroupProjectsCmd) + }, + expectOut: []string{"18", "lagoon-demo"}, + expectErr: false, + }, + // TODO: Seed variable data + { + name: "List Environment Variables", + cmdArgs: []string{"list", "variables", "--project=lagoon-demo", "--environment=main", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listVariablesCmd) + AddGenericFlags(listVariablesCmd) + }, + expectOut: []string{""}, + expectErr: false, + }, + // TODO: Seed variable data + { + name: "List Project Variables", + cmdArgs: []string{"list", "variables", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listVariablesCmd) + AddGenericFlags(listVariablesCmd) + }, + expectOut: []string{""}, + expectErr: false, + }, + { + name: "List user-groups", + cmdArgs: []string{"list", "user-groups", "--email-address=default-user@lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listUsersGroupsCmd) + AddGenericFlags(listUsersGroupsCmd) + }, + expectOut: []string{"project-lagoon-demo", "MAINTAINER"}, + expectErr: false, + }, + { + name: "List invokable-tasks", + cmdArgs: []string{"list", "invokable-tasks", "--project=lagoon-demo", "--environment=main", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listInvokableTasks) + AddGenericFlags(listInvokableTasks) + }, + expectOut: []string{"Maintainer task", "Developer task"}, + expectErr: false, + }, + { + name: "List project-groups", + cmdArgs: []string{"list", "project-groups", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectGroupsCmd) + AddGenericFlags(listProjectGroupsCmd) + }, + expectOut: []string{"lagoon-demo-group", "lagoon-group", "project-lagoon-demo"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/notificationsemail.go b/cmd/notificationsemail.go index bdd62a1a..89766487 100644 --- a/cmd/notificationsemail.go +++ b/cmd/notificationsemail.go @@ -86,7 +86,7 @@ It does not configure a project to send notifications to email though, you need "Organization", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -135,7 +135,7 @@ This command is used to add an existing email notification in Lagoon to a projec resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -191,7 +191,7 @@ var listProjectEmailsCmd = &cobra.Command{ "EmailAddress", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -240,7 +240,7 @@ var listAllEmailsCmd = &cobra.Command{ "EmailAddress", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -285,7 +285,7 @@ var deleteProjectEmailNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -326,7 +326,7 @@ var deleteEmailNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -399,7 +399,7 @@ var updateEmailNotificationCmd = &cobra.Command{ "EmailAddress", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, diff --git a/cmd/notificationsemail_test.go b/cmd/notificationsemail_test.go new file mode 100644 index 00000000..e93f19ad --- /dev/null +++ b/cmd/notificationsemail_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestEmailNotificationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Email Notification", + cmdArgs: []string{"add", "notification", "email", "--name=email-notification", "--email=test@test.com", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addNotificationEmailCmd) + AddGenericFlags(addNotificationEmailCmd) + }, + expectOut: []string{"email-notification", "test@test.com"}, + expectErr: false, + }, + { + name: "Add Email Notification to Project", + cmdArgs: []string{"add", "notification", "project-email", "--name=email-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectNotificationEmailCmd) + AddGenericFlags(addProjectNotificationEmailCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "List Project Email Notifications", + cmdArgs: []string{"list", "notification", "project-email", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectEmailsCmd) + AddGenericFlags(listProjectEmailsCmd) + }, + expectOut: []string{"email-notification", "test@test.com"}, + expectErr: false, + }, + { + name: "List all Email Notifications", + cmdArgs: []string{"list", "notification", "email", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllEmailsCmd) + AddGenericFlags(listAllEmailsCmd) + }, + expectOut: []string{"lagoon-demo", "email-notification", "test@test.com"}, + expectErr: false, + }, + // Unable test newname as incorrect data is returned via the API (fixed in PR#3706) + { + name: "Update an Email Notification", + cmdArgs: []string{"update", "notification", "email", "--name=email-notification", "--email=newemail@test.com", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateEmailNotificationCmd) + AddGenericFlags(updateEmailNotificationCmd) + }, + expectOut: []string{"email-notification", "newemail@test.com"}, + expectErr: false, + }, + { + name: "Delete an Email Notification from a Project", + cmdArgs: []string{"delete", "notification", "project-email", "--name=email-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectEmailNotificationCmd) + AddGenericFlags(deleteProjectEmailNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete an Email Notification", + cmdArgs: []string{"delete", "notification", "email", "--name=email-notification", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteEmailNotificationCmd) + AddGenericFlags(deleteEmailNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/notificationsrocketchat.go b/cmd/notificationsrocketchat.go index f1130028..1521a91d 100644 --- a/cmd/notificationsrocketchat.go +++ b/cmd/notificationsrocketchat.go @@ -94,7 +94,7 @@ It does not configure a project to send notifications to RocketChat though, you "Organization", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -144,7 +144,7 @@ This command is used to add an existing RocketChat notification in Lagoon to a p resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -202,7 +202,7 @@ var listProjectRocketChatsCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -253,7 +253,7 @@ var listAllRocketChatsCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -298,7 +298,7 @@ var deleteProjectRocketChatNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -339,7 +339,7 @@ var deleteRocketChatNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -419,7 +419,7 @@ var updateRocketChatNotificationCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, diff --git a/cmd/notificationsrocketchat_test.go b/cmd/notificationsrocketchat_test.go new file mode 100644 index 00000000..3e0132fd --- /dev/null +++ b/cmd/notificationsrocketchat_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestRocketChatNotificationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add RocketChat Notification", + cmdArgs: []string{"add", "notification", "rocketchat", "--name=rocketchat-notification", "--channel=test-channel", "--webhook=test-webhook", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addNotificationRocketchatCmd) + AddGenericFlags(addNotificationRocketchatCmd) + }, + expectOut: []string{"rocketchat-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + { + name: "Add RocketChat Notification to Project", + cmdArgs: []string{"add", "notification", "project-rocketchat", "--name=rocketchat-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectNotificationRocketChatCmd) + AddGenericFlags(addProjectNotificationRocketChatCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "List Project RocketChat Notifications", + cmdArgs: []string{"list", "notification", "project-rocketchat", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectRocketChatsCmd) + AddGenericFlags(listProjectRocketChatsCmd) + }, + expectOut: []string{"rocketchat-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + { + name: "List all RocketChat Notifications", + cmdArgs: []string{"list", "notification", "rocketchat", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllRocketChatsCmd) + AddGenericFlags(listAllRocketChatsCmd) + }, + expectOut: []string{"lagoon-demo", "rocketchat-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + // Unable test newname as incorrect data is returned via the API (fixed in PR#3706) + { + name: "Update a RocketChat Notification", + cmdArgs: []string{"update", "notification", "rocketchat", "--name=rocketchat-notification", "--webhook=new-webhook-test", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateRocketChatNotificationCmd) + AddGenericFlags(updateRocketChatNotificationCmd) + }, + expectOut: []string{"rocketchat-notification", "new-webhook-test", "test-channel"}, + expectErr: false, + }, + { + name: "Delete a RocketChat Notification from a Project", + cmdArgs: []string{"delete", "notification", "project-rocketchat", "--name=rocketchat-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectRocketChatNotificationCmd) + AddGenericFlags(deleteProjectRocketChatNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete a RocketChat Notification", + cmdArgs: []string{"delete", "notification", "rocketchat", "--name=rocketchat-notification", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteRocketChatNotificationCmd) + AddGenericFlags(deleteRocketChatNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/notificationsslack.go b/cmd/notificationsslack.go index 7032f3a2..5dc22c78 100644 --- a/cmd/notificationsslack.go +++ b/cmd/notificationsslack.go @@ -94,7 +94,7 @@ It does not configure a project to send notifications to Slack though, you need "Organization", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -142,7 +142,7 @@ This command is used to add an existing Slack notification in Lagoon to a projec resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -200,7 +200,7 @@ var listProjectSlacksCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -251,7 +251,7 @@ var listAllSlacksCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -296,7 +296,7 @@ var deleteProjectSlackNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -337,7 +337,7 @@ var deleteSlackNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -417,7 +417,7 @@ var updateSlackNotificationCmd = &cobra.Command{ "Channel", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, diff --git a/cmd/notificationsslack_test.go b/cmd/notificationsslack_test.go new file mode 100644 index 00000000..a2f76302 --- /dev/null +++ b/cmd/notificationsslack_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestSlackNotificationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Slack Notification", + cmdArgs: []string{"add", "notification", "slack", "--name=slack-notification", "--channel=test-channel", "--webhook=test-webhook", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addNotificationSlackCmd) + AddGenericFlags(addNotificationSlackCmd) + }, + expectOut: []string{"slack-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + { + name: "Add Slack Notification to Project", + cmdArgs: []string{"add", "notification", "project-slack", "--name=slack-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectNotificationSlackCmd) + AddGenericFlags(addProjectNotificationSlackCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "List Project Slack Notifications", + cmdArgs: []string{"list", "notification", "project-slack", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectSlacksCmd) + AddGenericFlags(listProjectSlacksCmd) + }, + expectOut: []string{"slack-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + { + name: "List all Slack Notifications", + cmdArgs: []string{"list", "notification", "slack", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllSlacksCmd) + AddGenericFlags(listAllSlacksCmd) + }, + expectOut: []string{"lagoon-demo", "slack-notification", "test-channel", "test-webhook"}, + expectErr: false, + }, + // Unable test newname as incorrect data is returned via the API (fixed in PR#3706) + { + name: "Update a Slack Notification", + cmdArgs: []string{"update", "notification", "slack", "--name=slack-notification", "--webhook=new-webhook-test", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateSlackNotificationCmd) + AddGenericFlags(updateSlackNotificationCmd) + }, + expectOut: []string{"slack-notification", "new-webhook-test", "test-channel"}, + expectErr: false, + }, + { + name: "Delete a Slack Notification from a Project", + cmdArgs: []string{"delete", "notification", "project-slack", "--name=slack-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectSlackNotificationCmd) + AddGenericFlags(deleteProjectSlackNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete a Slack Notification", + cmdArgs: []string{"delete", "notification", "slack", "--name=slack-notification", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteSlackNotificationCmd) + AddGenericFlags(deleteSlackNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/notificationsteams.go b/cmd/notificationsteams.go index d267fb66..fc08734c 100644 --- a/cmd/notificationsteams.go +++ b/cmd/notificationsteams.go @@ -87,7 +87,7 @@ It does not configure a project to send notifications to Microsoft Teams though, "Organization", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -135,7 +135,7 @@ This command is used to add an existing Microsoft Teams notification in Lagoon t resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -191,7 +191,7 @@ var listProjectMicrosoftTeamsCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -240,7 +240,7 @@ var listAllMicrosoftTeamsCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -285,7 +285,7 @@ var deleteProjectMicrosoftTeamsNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -326,7 +326,7 @@ var deleteMicrosoftTeamsNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -399,7 +399,7 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, diff --git a/cmd/notificationsteams_test.go b/cmd/notificationsteams_test.go new file mode 100644 index 00000000..b9973fe9 --- /dev/null +++ b/cmd/notificationsteams_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestMicrosoftTeamsNotificationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add MicrosoftTeams Notification", + cmdArgs: []string{"add", "notification", "microsoftteams", "--name=microsoftteams-notification", "--webhook=test-webhook", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addNotificationMicrosoftTeamsCmd) + AddGenericFlags(addNotificationMicrosoftTeamsCmd) + }, + expectOut: []string{"microsoftteams-notification", "test-webhook"}, + expectErr: false, + }, + { + name: "Add MicrosoftTeams Notification to Project", + cmdArgs: []string{"add", "notification", "project-microsoftteams", "--name=microsoftteams-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectNotificationMicrosoftTeamsCmd) + AddGenericFlags(addProjectNotificationMicrosoftTeamsCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "List Project MicrosoftTeams Notifications", + cmdArgs: []string{"list", "notification", "project-microsoftteams", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectMicrosoftTeamsCmd) + AddGenericFlags(listProjectMicrosoftTeamsCmd) + }, + expectOut: []string{"microsoftteams-notification", "test-webhook"}, + expectErr: false, + }, + { + name: "List all MicrosoftTeams Notifications", + cmdArgs: []string{"list", "notification", "microsoftteams", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllMicrosoftTeamsCmd) + AddGenericFlags(listAllMicrosoftTeamsCmd) + }, + expectOut: []string{"lagoon-demo", "microsoftteams-notification", "test-webhook"}, + expectErr: false, + }, + // Unable test newname as incorrect data is returned via the API (fixed in PR#3706) + { + name: "Update a MicrosoftTeams Notification", + cmdArgs: []string{"update", "notification", "microsoftteams", "--name=microsoftteams-notification", "--webhook=new-webhook-test", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateMicrosoftTeamsNotificationCmd) + AddGenericFlags(updateMicrosoftTeamsNotificationCmd) + }, + expectOut: []string{"microsoftteams-notification", "new-webhook-test"}, + expectErr: false, + }, + { + name: "Delete a MicrosoftTeams Notification from a Project", + cmdArgs: []string{"delete", "notification", "project-microsoftteams", "--name=microsoftteams-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectMicrosoftTeamsNotificationCmd) + AddGenericFlags(deleteProjectMicrosoftTeamsNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete a MicrosoftTeams Notification", + cmdArgs: []string{"delete", "notification", "microsoftteams", "--name=microsoftteams-notification", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteMicrosoftTeamsNotificationCmd) + AddGenericFlags(deleteMicrosoftTeamsNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/notificationswebhook.go b/cmd/notificationswebhook.go index 58eee15a..57a8d1c2 100644 --- a/cmd/notificationswebhook.go +++ b/cmd/notificationswebhook.go @@ -87,7 +87,7 @@ It does not configure a project to send notifications to webhook though, you nee "Organization", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -135,7 +135,7 @@ This command is used to add an existing webhook notification in Lagoon to a proj resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -191,7 +191,7 @@ var listProjectWebhooksCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -240,7 +240,7 @@ var listAllWebhooksCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -285,7 +285,7 @@ var deleteProjectWebhookNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -326,7 +326,7 @@ var deleteWebhookNotificationCmd = &cobra.Command{ resultData := output.Result{ Result: result.DeleteNotification, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -399,7 +399,7 @@ var updateWebhookNotificationCmd = &cobra.Command{ "Webhook", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, diff --git a/cmd/notificationswebhook_test.go b/cmd/notificationswebhook_test.go new file mode 100644 index 00000000..142ae3fd --- /dev/null +++ b/cmd/notificationswebhook_test.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestWebhookNotificationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Webhook Notification", + cmdArgs: []string{"add", "notification", "webhook", "--name=webhook-notification", "--webhook=test-webhook", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addNotificationWebhookCmd) + AddGenericFlags(addNotificationWebhookCmd) + }, + expectOut: []string{"webhook-notification", "test-webhook"}, + expectErr: false, + }, + { + name: "Add Webhook Notification to Project", + cmdArgs: []string{"add", "notification", "project-webhook", "--name=webhook-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectNotificationWebhookCmd) + AddGenericFlags(addProjectNotificationWebhookCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "List Project Webhook Notifications", + cmdArgs: []string{"list", "notification", "project-webhook", "--project=lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listProjectWebhooksCmd) + AddGenericFlags(listProjectWebhooksCmd) + }, + expectOut: []string{"webhook-notification", "test-webhook"}, + expectErr: false, + }, + { + name: "List all Webhook Notifications", + cmdArgs: []string{"list", "notification", "webhook", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(listCmd) + listCmd.AddCommand(listAllWebhooksCmd) + AddGenericFlags(listAllWebhooksCmd) + }, + expectOut: []string{"lagoon-demo", "webhook-notification", "test-webhook"}, + expectErr: false, + }, + // Unable test newname as incorrect data is returned via the API (fixed in PR#3706) + { + name: "Update a Webhook Notification", + cmdArgs: []string{"update", "notification", "webhook", "--name=webhook-notification", "--webhook=new-webhook-test", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateWebhookNotificationCmd) + AddGenericFlags(updateWebhookNotificationCmd) + }, + expectOut: []string{"webhook-notification", "new-webhook-test"}, + expectErr: false, + }, + { + name: "Delete a Webhook Notification from a Project", + cmdArgs: []string{"delete", "notification", "project-webhook", "--name=webhook-notification", "--project=lagoon-demo", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectWebhookNotificationCmd) + AddGenericFlags(deleteProjectWebhookNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete a Webhook Notification", + cmdArgs: []string{"delete", "notification", "webhook", "--name=webhook-notification", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteWebhookNotificationCmd) + AddGenericFlags(deleteWebhookNotificationCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/organization.go b/cmd/organization.go index 1685a2b9..f5737d3f 100644 --- a/cmd/organization.go +++ b/cmd/organization.go @@ -90,7 +90,7 @@ var addOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -139,7 +139,7 @@ var deleteOrganizationCmd = &cobra.Command{ resultData := output.Result{ Result: organization.Name, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -229,7 +229,7 @@ var updateOrganizationCmd = &cobra.Command{ "Organization Name": result.Name, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } diff --git a/cmd/organization_test.go b/cmd/organization_test.go new file mode 100644 index 00000000..df05886a --- /dev/null +++ b/cmd/organization_test.go @@ -0,0 +1,81 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestOrganizationCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + }{ + { + name: "Add Organization", + cmdArgs: []string{"add", "organization", + "--organization-name=test-organization", + "--friendly-name=Test Organization", + "--description=A test organization", + "--project-quota=10", + "--environment-quota=20", + "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addOrganizationCmd) + AddGenericFlags(addOrganizationCmd) + }, + expectOut: []string{"success", "test-organization"}, + expectErr: false, + }, + { + name: "Delete Organization", + cmdArgs: []string{"delete", "organization", + "--organization-name=test-organization", + "--force", + "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteOrganizationCmd) + AddGenericFlags(deleteOrganizationCmd) + }, + expectOut: []string{"result", "test-organization"}, + expectErr: false, + }, + // TODO: Remaining Organization commands + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/project.go b/cmd/project.go index d4ef7079..25cd0cc2 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -50,7 +50,7 @@ var deleteProjectCmd = &cobra.Command{ resultData := output.Result{ Result: "success", } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, @@ -203,7 +203,7 @@ var addProjectCmd = &cobra.Command{ if organizationName != "" { resultData.ResultData["Organization"] = organizationName } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -377,7 +377,7 @@ var updateProjectCmd = &cobra.Command{ } if project.Name == "" { outputOptions.Error = fmt.Sprintf("Project '%s' not found\n", cmdProjectName) - output.RenderError(outputOptions.Error, outputOptions) + output.RenderError(outputOptions.Error, outputOptions, cmd) return nil } projectUpdate, err := lagoon.UpdateProject(context.TODO(), int(project.ID), projectPatch, lc) @@ -391,7 +391,7 @@ var updateProjectCmd = &cobra.Command{ "Project Name": projectUpdate.Name, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) return nil }, } @@ -463,7 +463,7 @@ var listProjectByMetadata = &cobra.Command{ output.RenderOutput(output.Table{ Header: header, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -513,7 +513,7 @@ var getProjectMetadata = &cobra.Command{ output.RenderOutput(output.Table{ Header: header, Data: data, - }, outputOptions) + }, outputOptions, cmd) return nil }, } @@ -572,7 +572,7 @@ var updateProjectMetadata = &cobra.Command{ "Metadata", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -628,7 +628,7 @@ var deleteProjectMetadataByKey = &cobra.Command{ "Metadata", }, Data: data, - }, outputOptions) + }, outputOptions, cmd) } return nil }, @@ -694,7 +694,7 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ "Organization Name": organizationName, }, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, diff --git a/cmd/project_test.go b/cmd/project_test.go new file mode 100644 index 00000000..0485ceef --- /dev/null +++ b/cmd/project_test.go @@ -0,0 +1,106 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestProjectCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + { + name: "Add Project", + cmdArgs: []string{"add", "project", "--project=test-project", "--production-environment=main", "--openshift=4", "--git-url=https://github.com/lagoon-examples/drupal10-base", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectCmd) + AddGenericFlags(addProjectCmd) + }, + expectOut: []string{"success", "test-project", "https://github.com/lagoon-examples/drupal10-base"}, + expectErr: false, + }, + { + name: "Add Project to an Organization", + cmdArgs: []string{"add", "project", "--project=test-organization-project", "--organization-name=lagoon-demo-organization", "--production-environment=main", "--openshift=4", "--git-url=https://github.com/lagoon-examples/drupal10-base", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addProjectCmd) + AddGenericFlags(addProjectCmd) + }, + expectOut: []string{"success", "test-organization-project", "https://github.com/lagoon-examples/drupal10-base", "lagoon-demo-organization"}, + expectErr: false, + }, + { + name: "Update a Project", + cmdArgs: []string{"update", "project", "--project=lagoon-demo", "--auto-idle=0", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateProjectCmd) + AddGenericFlags(updateProjectCmd) + }, + expectOut: []string{"success", "lagoon-demo"}, + expectErr: false, + }, + { + name: "Delete a Project", + cmdArgs: []string{"delete", "project", "--project=test-project", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteProjectCmd) + AddGenericFlags(deleteProjectCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Remove a Project from an Organization", + cmdArgs: []string{"delete", "organization-project", "--project=test-organization-project", "--organization-name=lagoon-demo-organization", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(removeProjectFromOrganizationCmd) + AddGenericFlags(removeProjectFromOrganizationCmd) + }, + expectOut: []string{"success", "test-organization-project", "lagoon-demo-organization"}, + expectErr: false, + }, + // TODO: Add tests for metadata commands + } + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.NotEmpty(t, err) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + + }) + } +} diff --git a/cmd/shared.go b/cmd/shared.go index 2cc479d1..ec06cae6 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -2,6 +2,8 @@ package cmd import ( "fmt" + "github.com/spf13/cobra" + "github.com/spf13/pflag" "os" "strings" @@ -99,3 +101,21 @@ func requiredInputCheck(fieldsAndValues ...string) error { } return nil } + +// SetUpRootCmdFlags sets up the flags for the root command +func SetUpRootCmdFlags() { + rootCmd.Flags().StringP("config-file", "", "", "Path to the config file to use (must be *.yml or *.yaml)") + rootCmd.Flags().StringVarP(&cmdLagoon, "lagoon", "l", "", "The Lagoon instance to interact with") +} + +// AddGenericFlags adds the generic flags to the command being executed. --debug, --output-json, --project, --environment, --force +// Instantiates an explicit flagset for each command to avoid 'flag redefined' errors on multiple tests containing the same command +func AddGenericFlags(cmd *cobra.Command) { + flags := pflag.FlagSet{} + flags.BoolVarP(&debugEnable, "debug", "", false, "Enable debugging output (if supported)") + flags.BoolVarP(&outputOptions.JSON, "output-json", "", false, "Output as JSON (if supported)") + flags.StringVarP(&cmdProjectName, "project", "p", "", "Specify a project to use") + flags.StringVarP(&cmdProjectEnvironment, "environment", "e", "", "Specify an environment to use") + flags.BoolVarP(&forceAction, "force", "", false, "Force yes on prompts (if supported)") + cmd.Flags().AddFlagSet(&flags) +} diff --git a/cmd/tasks_test.go b/cmd/tasks_test.go new file mode 100644 index 00000000..5895ce39 --- /dev/null +++ b/cmd/tasks_test.go @@ -0,0 +1,64 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestTaskCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + // TODO: Seed task data & include cli service for envs + { + name: "Get Task", + cmdArgs: []string{"get", "task-by-id", "--id=1", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getTaskByID) + AddGenericFlags(getTaskByID) + }, + expectOut: []string{""}, + expectErr: false, + }, + } + + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + cmd.SetArgs(tt.cmdArgs) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.Contains(t, err.Error(), tt.expectedErrString) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + }) + } +} diff --git a/cmd/users_test.go b/cmd/users_test.go new file mode 100644 index 00000000..f5a9110e --- /dev/null +++ b/cmd/users_test.go @@ -0,0 +1,140 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestUserCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + { + name: "Add User", + cmdArgs: []string{"add", "user", "--email=user@test.com", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addUserCmd) + AddGenericFlags(addUserCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Add User SSH Key", + cmdArgs: []string{"add", "user-sshkey", "--email=user@test.com", "--keyvalue=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINA0ITV2gbDc6noYeWaqfxTYpaEKq7HzU3+F71XGhSL/", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addUserSSHKeyCmd) + AddGenericFlags(addUserSSHKeyCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete User SSH Key", + cmdArgs: []string{"delete", "user-sshkey", "--id=2", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteSSHKeyCmd) + AddGenericFlags(deleteSSHKeyCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Update User", + cmdArgs: []string{"update", "user", "--current-email=user@test.com", "--first-name=test", "--last-name=user", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(updateCmd) + updateCmd.AddCommand(updateUserCmd) + AddGenericFlags(updateUserCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete User", + cmdArgs: []string{"delete", "user", "--email=user@test.com", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteUserCmd) + AddGenericFlags(deleteUserCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Get User SSK Keys", + cmdArgs: []string{"get", "user-sshkeys", "--email=default-user@lagoon-demo", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getUserKeysCmd) + AddGenericFlags(getUserKeysCmd) + }, + expectOut: []string{"default-user@lagoon-demo", "ssh-ed25519"}, + expectErr: false, + }, + { + name: "Get All User SSK Keys", + cmdArgs: []string{"get", "all-user-sshkeys", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getAllUserKeysCmd) + AddGenericFlags(getAllUserKeysCmd) + }, + expectOut: []string{"default-user@lagoon-demo", "ci-customer-user-rsa@example.com", "ci-customer-user-ecdsa@example.com"}, + expectErr: false, + }, + { + name: "Get All User SSK Keys in group", + cmdArgs: []string{"get", "all-user-sshkeys", "--name=ci-group", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(getCmd) + getCmd.AddCommand(getAllUserKeysCmd) + AddGenericFlags(getAllUserKeysCmd) + }, + expectOut: []string{"ci-customer-user-rsa@example.com", "ci-customer-user-ecdsa@example.com"}, + expectErr: false, + }, + } + + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + cmd.SetArgs(tt.cmdArgs) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.Contains(t, err.Error(), tt.expectedErrString) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + }) + } +} diff --git a/cmd/variables.go b/cmd/variables.go index 88e6bc5a..a1864e89 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -88,9 +88,9 @@ var addVariableCmd = &cobra.Command{ output.RenderOutput(output.Table{ Header: header, Data: data, - }, outputOptions) + }, outputOptions, cmd) } else { - output.RenderInfo(fmt.Sprintf("variable %s remained unchanged", varName), outputOptions) + output.RenderInfo(fmt.Sprintf("variable %s remained unchanged", varName), outputOptions, cmd) } return nil }, @@ -142,7 +142,7 @@ var deleteVariableCmd = &cobra.Command{ resultData := output.Result{ Result: deleteResult.DeleteEnvVar, } - output.RenderResult(resultData, outputOptions) + output.RenderResult(resultData, outputOptions, cmd) } return nil }, diff --git a/cmd/variables_test.go b/cmd/variables_test.go new file mode 100644 index 00000000..ecabfee1 --- /dev/null +++ b/cmd/variables_test.go @@ -0,0 +1,96 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/spf13/cobra" +) + +func TestVariableCommands(t *testing.T) { + tests := []struct { + name string + cmdArgs []string + setupCmd func(*cobra.Command, pflag.FlagSet) + expectOut []string + expectErr bool + expectedErrString string + }{ + { + name: "Add Variable to project", + cmdArgs: []string{"add", "variable", "--project=lagoon-demo", "--name=testProjectVariable", "--value=testProjectValue", "--scope=build", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addVariableCmd) + AddGenericFlags(addVariableCmd) + }, + expectOut: []string{"testProjectVariable", "testProjectValue", "build"}, + expectErr: false, + }, + { + name: "Add Variable to environment", + cmdArgs: []string{"add", "variable", "--project=lagoon-demo", "--environment=dev", "--name=testEnvironmentVariable", "--value=testEnvironmentValue", "--scope=runtime", "--output-json"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(addCmd) + addCmd.AddCommand(addVariableCmd) + AddGenericFlags(addVariableCmd) + }, + expectOut: []string{"testEnvironmentVariable", "testEnvironmentValue", "runtime"}, + expectErr: false, + }, + { + name: "Delete Variable from project", + cmdArgs: []string{"delete", "variable", "--project=lagoon-demo", "--name=testProjectVariable", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteVariableCmd) + AddGenericFlags(deleteVariableCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + { + name: "Delete Variable from environment", + cmdArgs: []string{"delete", "variable", "--project=lagoon-demo", "--environment=dev", "--name=testEnvironmentVariable", "--output-json", "--force"}, + setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { + cmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteVariableCmd) + AddGenericFlags(deleteVariableCmd) + }, + expectOut: []string{"success"}, + expectErr: false, + }, + } + + SetUpRootCmdFlags() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "root"} + cmd.SetArgs(tt.cmdArgs) + flags := pflag.FlagSet{} + tt.setupCmd(cmd, flags) + + var out bytes.Buffer + cmd.SetOut(&out) + cmd.SetErr(&out) + + cmd.SetArgs(tt.cmdArgs) + + err := cmd.Execute() + if err != nil && tt.expectErr { + assert.Contains(t, err.Error(), tt.expectedErrString) + fmt.Println("err:", err) + return + } else if err != nil { + t.Fatalf("Error executing command: %v", err) + } + + for _, eo := range tt.expectOut { + assert.Contains(t, out.String(), eo) + } + }) + } +} diff --git a/pkg/output/main.go b/pkg/output/main.go index e40e24f0..920d2813 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -3,6 +3,7 @@ package output import ( "encoding/json" "fmt" + "github.com/spf13/cobra" "os" "strings" @@ -56,13 +57,36 @@ func RenderJSON(data interface{}, opts Options) { fmt.Println(string(jsonBytes)) } +// JSONTestData for use with api tests. +func JSONTestData(data interface{}, opts Options, cmd *cobra.Command) { + var jsonBytes []byte + var err error + if opts.Pretty { + jsonBytes, err = json.MarshalIndent(data, "", " ") + if err != nil { + panic(err) + } + } else { + jsonBytes, err = json.Marshal(data) + if err != nil { + panic(err) + } + } + // Allows output to be captured for tests + fmt.Fprintf(cmd.OutOrStdout(), string(jsonBytes)) +} + // RenderError . -func RenderError(errorMsg string, opts Options) { +func RenderError(errorMsg string, opts Options, cmd ...*cobra.Command) { if opts.JSON { jsonData := Result{ Error: trimQuotes(errorMsg), } - RenderJSON(jsonData, opts) + if cmd != nil { + JSONTestData(jsonData, opts, cmd[0]) + } else { + RenderJSON(jsonData, opts) + } } else { //fmt.Println(fmt.Sprintf("Error: %s", aurora.Yellow(trimQuotes(errorMsg)))) fmt.Println("Error:", trimQuotes(errorMsg)) @@ -70,21 +94,29 @@ func RenderError(errorMsg string, opts Options) { } // RenderInfo . -func RenderInfo(infoMsg string, opts Options) { +func RenderInfo(infoMsg string, opts Options, cmd ...*cobra.Command) { if opts.JSON { jsonData := Result{ Info: trimQuotes(infoMsg), } - RenderJSON(jsonData, opts) + if cmd != nil { + JSONTestData(jsonData, opts, cmd[0]) + } else { + RenderJSON(jsonData, opts) + } } else { fmt.Println("Info:", trimQuotes(infoMsg)) } } // RenderResult . -func RenderResult(result Result, opts Options) { +func RenderResult(result Result, opts Options, cmd ...*cobra.Command) { if opts.JSON { - RenderJSON(result, opts) + if cmd != nil { + JSONTestData(result, opts, cmd[0]) + } else { + RenderJSON(result, opts) + } } else { if trimQuotes(result.Result) == "success" { fmt.Printf("Result: %s\n", aurora.Green(trimQuotes(result.Result))) @@ -106,7 +138,7 @@ func RenderResult(result Result, opts Options) { } // RenderOutput . -func RenderOutput(data Table, opts Options) { +func RenderOutput(data Table, opts Options, cmd ...*cobra.Command) { if opts.Debug { fmt.Printf("%s\n", aurora.Yellow("Final result:")) } @@ -124,7 +156,11 @@ func RenderOutput(data Table, opts Options) { returnedData := map[string]interface{}{ "data": rawData, } - RenderJSON(returnedData, opts) + if cmd != nil { + JSONTestData(returnedData, opts, cmd[0]) + } else { + RenderJSON(returnedData, opts) + } } else { // otherwise render a table if opts.Error != "" { diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..415e23e5 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,34 @@ +SHELL := /bin/bash + +KCADM = /opt/jboss/keycloak/bin/kcadm.sh +KCADM_CONFIG = /tmp/.keycloak/kcadm.config +KCADM_STRING = --server http://$$(hostname -i):8080/auth --user $$KEYCLOAK_ADMIN_USER --password $$KEYCLOAK_ADMIN_PASSWORD --realm master +KCADM_LOGIN = $(KCADM) config credentials --config $(KCADM_CONFIG) $(KCADM_STRING) + +.PHONY: build-lagoon +build-lagoon: + docker compose up -d --quiet-pull + $(MAKE) wait-for-keycloak + @echo "\nYour Lagoon stack is now running locally - use 'GRAPHQL_API=http://0.0.0.0:33000/graphql KEYCLOAK_API=http://0.0.0.0:38088/auth' as the variables to access it\n" + +.PHONY: wait-for-keycloak +wait-for-keycloak: + $(info Waiting for Keycloak to be ready....) + grep -m 1 "Config of Keycloak done." <(docker compose --compatibility logs -f keycloak 2>&1) + +.PHONY: keycloak-setup +keycloak-setup: + docker compose exec keycloak bash -c "/upload/configure-keycloak.sh" + +.PHONY: reload-data +reload-data: + docker compose up -d local-api-data-watcher-pusher + +.PHONY: down +down: + docker compose down --remove-orphans --volumes + +.PHONY: up +up: + $(MAKE) build-lagoon + $(MAKE) keycloak-setup diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml new file mode 100644 index 00000000..e2ddbc8f --- /dev/null +++ b/test/docker-compose.yaml @@ -0,0 +1,79 @@ +# Placeholder for the api testing, to be replaced with existing make cmd in uselagoon/lagoon +version: '3.2' + +services: + api-db: + image: uselagoon/api-db:latest + networks: + - default + broker: + image: uselagoon/broker:latest + restart: on-failure + networks: + - default + api-init: + image: uselagoon/api:latest + command: ./node_modules/.bin/knex migrate:latest --cwd /app/services/api/database + depends_on: + - api-db + - keycloak + api-lagoon-migrations: + image: uselagoon/api:latest + command: sh -c "./node_modules/.bin/tsc && node -r dotenv-extended/config dist/migrations/lagoon/migration.js" + environment: + - KEYCLOAK_URL=http://172.17.0.1:38088 + depends_on: + api-init: + condition: service_completed_successfully # don't start the lagoon migrations until the db migrations is completed + keycloak: + condition: service_started + api: + image: uselagoon/api:latest + ports: + - '3000:3000' + networks: + - default + environment: + - KEYCLOAK_URL=http://172.17.0.1:38088 + - NODE_ENV=development + - OPENSEARCH_INTEGRATION_ENABLED=false + - DISABLE_CORE_HARBOR=true + - CI=${CI:-true} + - S3_FILES_HOST=http://0.0.0.0:39000 + - S3_BAAS_ACCESS_KEY_ID=minio + - S3_BAAS_SECRET_ACCESS_KEY=minio123 + - CONSOLE_LOGGING_LEVEL=trace + depends_on: + - api-lagoon-migrations + api-redis: + image: uselagoon/api-redis:latest + keycloak: + image: uselagoon/keycloak:latest + depends_on: + - keycloak-db + ports: + - '38088:8080' + volumes: + - ./keycloak:/upload + environment: + - KEYCLOAK_FRONTEND_URL=http://0.0.0.0:38088/auth + keycloak-db: + image: uselagoon/keycloak-db:latest + local-minio: + image: minio/minio + entrypoint: sh + command: -c 'mkdir -p /export/restores && mkdir -p /export/lagoon-files && mkdir -p /export/harbor-images && minio server /export --console-address ":9001" ' + ports: + - '39000:9000' + - '39001:9001' + environment: + - MINIO_ROOT_USER=minio + - MINIO_ROOT_PASSWORD=minio123 + local-api-data-watcher-pusher: + image: uselagoon/local-api-data-watcher-pusher:latest + depends_on: + - api + command: ["bash", "-c", " + wait-for api:3000 -t 600; + /home/data-init-push.sh; + "] diff --git a/test/keycloak/configure-keycloak.sh b/test/keycloak/configure-keycloak.sh new file mode 100755 index 00000000..0aa788c0 --- /dev/null +++ b/test/keycloak/configure-keycloak.sh @@ -0,0 +1,52 @@ +function is_keycloak_running { + local http_code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/auth/admin/realms) + if [[ $http_code -eq 401 ]]; then + return 0 + else + return 1 + fi +} + +function configure_user_passwords { + + LAGOON_DEMO_USERS=("guest@example.com" "reporter@example.com" "developer@example.com" "maintainer@example.com" "owner@example.com") + LAGOON_DEMO_ORG_USERS=("orguser@example.com" "orgviewer@example.com" "orgowner@example.com" "platformowner@example.com") + + for i in ${LAGOON_DEMO_USERS[@]} + do + echo Configuring password for $i + /opt/keycloak/bin/kcadm.sh set-password --config $CONFIG_PATH --username $i -p $i --target-realm Lagoon + done + + for i in ${LAGOON_DEMO_ORG_USERS[@]} + do + echo Configuring password for $i + /opt/keycloak/bin/kcadm.sh set-password --config $CONFIG_PATH --username $i -p $i --target-realm Lagoon + done +} + +function configure_platformowner { + echo Configuring platform owner role + /opt/keycloak/bin/kcadm.sh add-roles --uusername platformowner@example.com --rolename platform-owner --config $CONFIG_PATH --target-realm Lagoon +} + +function configure_keycloak { + until is_keycloak_running; do + echo Keycloak still not running, waiting 5 seconds + sleep 5 + done + + # Set the config file path because $HOME/.keycloak/kcadm.config resolves to /opt/jboss/?/.keycloak/kcadm.config for some reason, causing it to fail + CONFIG_PATH=/tmp/kcadm.config + + echo Keycloak is running, proceeding with configuration + + /opt/keycloak/bin/kcadm.sh config credentials --config $CONFIG_PATH --server http://localhost:8080/auth --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD --realm master + + configure_user_passwords + configure_platformowner + + echo "Config of Keycloak users done" +} + +configure_keycloak \ No newline at end of file From aaa977070a3bb2c18c451403ea6e89e34c4cadc2 Mon Sep 17 00:00:00 2001 From: cgoodwin90 Date: Wed, 10 Jul 2024 18:10:14 +1000 Subject: [PATCH 3/3] Fixes errant changes --- Makefile | 53 +++++++++++++++++++++++++++----------------- cmd/deploy.go | 12 ++++++---- cmd/project_test.go | 4 ++-- local-dev/config.tpl | 1 + 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 691c3fe1..15779bfe 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,10 @@ api-tests: gen # upstream CI_BUILD_TAG ?= lagoon-cli CORE_REPO=https://github.com/uselagoon/lagoon.git -CORE_TREEISH=main +CORE_TREEISH=make-export-refactoring + +LAGOON_CORE_IMAGE_REPO=testlagoon +LAGOON_CORE_IMAGE_TAG=main TEMP_CONFIG_FILE := temp_config.yaml @@ -133,23 +136,33 @@ generate-config: clean-config: @rm -f $(TEMP_CONFIG_FILE) -# TODO - Update with UI-PR#266 -.PHONY: test-with-api -test-with-api: +.PHONY: cli-tests-with-development-api +cli-tests-with-development-api: development-api + TOKEN=$$(docker run -e JWTSECRET=super-secret-string \ + -e JWTAUDIENCE=api.dev \ + -e JWTUSER=localadmin \ + uselagoon/tests \ + python3 /ansible/tasks/api/admin_token.py) \ + && $(MAKE) generate-config TOKEN=$$TOKEN \ + && $(MAKE) api-tests \ + && $(MAKE) clean-config \ + && $(MAKE) CI_BUILD_TAG=$(CI_BUILD_TAG) development-api-down + +.PHONY: development-api +development-api: export LAGOON_CORE=$$(mktemp -d ./lagoon-core.XXX) \ - && git clone $(CORE_REPO) "$$LAGOON_CORE" \ - && cd "$$LAGOON_CORE" \ - && git checkout $(CORE_TREEISH) \ - && TOKEN=$$(docker run -e JWTSECRET=super-secret-string \ - -e JWTAUDIENCE=api.dev \ - -e JWTUSER=localadmin \ - uselagoon/tests \ - python3 /ansible/tasks/api/admin_token.py) \ - && IMAGE_REPO=uselagoon docker compose -p $(CI_BUILD_TAG) --compatibility up -d api api-db actions-handler local-api-data-watcher-pusher keycloak keycloak-db broker api-redis logs2notifications local-minio mailhog \ - && $(MAKE) CI_BUILD_TAG=$(CI_BUILD_TAG) wait-for-keycloak \ - && cd .. \ - && $(MAKE) generate-config TOKEN=$$TOKEN \ - && $(MAKE) api-tests \ - && $(MAKE) clean-config \ - && cd "$$LAGOON_CORE" \ - && $(MAKE) CI_BUILD_TAG=$(CI_BUILD_TAG) down + && git clone $(CORE_REPO) "$$LAGOON_CORE" \ + && cd "$$LAGOON_CORE" \ + && git checkout $(CORE_TREEISH) \ + && IMAGE_REPO=$(LAGOON_CORE_IMAGE_REPO) IMAGE_REPO_TAG=$(LAGOON_CORE_IMAGE_TAG) COMPOSE_STACK_NAME=core-$(CI_BUILD_TAG) docker compose -p core-$(CI_BUILD_TAG) pull \ + && IMAGE_REPO=$(LAGOON_CORE_IMAGE_REPO) IMAGE_REPO_TAG=$(LAGOON_CORE_IMAGE_TAG) COMPOSE_STACK_NAME=core-$(CI_BUILD_TAG) $(MAKE) compose-api-logs-development + +.PHONY: development-api-down +development-api-down: + cd lagoon-core* && \ + docker-compose -p core-$(CI_BUILD_TAG) --compatibility down -v --remove-orphans + +.PHONY: down +down: + $(MAKE) development-api-down + docker-compose -p $(CI_BUILD_TAG) --compatibility down -v --remove-orphans diff --git a/cmd/deploy.go b/cmd/deploy.go index ed6126b9..c3b99d5b 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -82,7 +82,8 @@ use 'lagoon deploy latest' instead`, return err } resultData := output.Result{Result: result.DeployEnvironmentBranch} - output.RenderResult(resultData, outputOptions, cmd) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -146,7 +147,8 @@ var deployPromoteCmd = &cobra.Command{ return err } resultData := output.Result{Result: result.DeployEnvironmentPromote} - output.RenderResult(resultData, outputOptions, cmd) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -208,7 +210,8 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo return err } resultData := output.Result{Result: result.DeployEnvironmentLatest} - output.RenderResult(resultData, outputOptions, cmd) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, @@ -296,7 +299,8 @@ This pullrequest may not already exist as an environment in lagoon.`, return err } resultData := output.Result{Result: result.DeployEnvironmentPullrequest} - output.RenderResult(resultData, outputOptions, cmd) + r := output.RenderResult(resultData, outputOptions) + fmt.Fprintf(cmd.OutOrStdout(), "%s", r) } return nil }, diff --git a/cmd/project_test.go b/cmd/project_test.go index 2863fc4b..cfa46dad 100644 --- a/cmd/project_test.go +++ b/cmd/project_test.go @@ -21,7 +21,7 @@ func TestAPIProjectCommands(t *testing.T) { }{ { name: "Add Project", - cmdArgs: []string{"add", "project", "--project=test-project", "--production-environment=main", "--openshift=4", "--git-url=https://github.com/lagoon-examples/drupal10-base"}, + cmdArgs: []string{"add", "project", "--project=test-project", "--production-environment=main", "--deploytarget=4", "--git-url=https://github.com/lagoon-examples/drupal10-base"}, setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { cmd.AddCommand(addCmd) addCmd.AddCommand(addProjectCmd) @@ -31,7 +31,7 @@ func TestAPIProjectCommands(t *testing.T) { }, { name: "Add Project to an Organization", - cmdArgs: []string{"add", "project", "--project=test-organization-project", "--organization-name=lagoon-demo-organization", "--production-environment=main", "--openshift=4", "--git-url=https://github.com/lagoon-examples/drupal10-base"}, + cmdArgs: []string{"add", "project", "--project=test-organization-project", "--organization-name=lagoon-demo-organization", "--production-environment=main", "--deploytarget=4", "--git-url=https://github.com/lagoon-examples/drupal10-base"}, setupCmd: func(cmd *cobra.Command, flags pflag.FlagSet) { cmd.AddCommand(addCmd) addCmd.AddCommand(addProjectCmd) diff --git a/local-dev/config.tpl b/local-dev/config.tpl index 0e1a6efa..8276512d 100644 --- a/local-dev/config.tpl +++ b/local-dev/config.tpl @@ -6,3 +6,4 @@ lagoons: hostname: "localhost" port: "2020" token: ${TOKEN} + version: v1.9.0