diff --git a/cmd/get.go b/cmd/get.go index 6f067d99..0e1c1042 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strconv" + "strings" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -224,24 +225,55 @@ var getProjectKeyCmd = &cobra.Command{ Use: "project-key", Aliases: []string{"pk"}, Short: "Get a projects public key", - Run: func(cmd *cobra.Command, args []string) { - getProjectFlags := parseGetFlags(*cmd.Flags()) - if getProjectFlags.Project == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + PreRunE: func(_ *cobra.Command, _ []string) error { + return validateTokenE(lagoonCLIConfig.Current) + }, + RunE: func(cmd *cobra.Command, args []string) error { + debug, err := cmd.Flags().GetBool("debug") + if err != nil { + return err } - returnedJSON, err := pClient.GetProjectKey(getProjectFlags.Project, revealValue) - handleError(err) - var dataMain output.Table - err = json.Unmarshal([]byte(returnedJSON), &dataMain) - handleError(err) + reveal, err := cmd.Flags().GetBool("reveal") + if err != nil { + return err + } + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err + } + + current := lagoonCLIConfig.Current + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, + debug) + + projectKey, err := l.GetProjectKeyByName(context.TODO(), cmdProjectName, reveal, lc) + projectKeys := []string{projectKey.PublicKey} + if projectKey.PrivateKey != "" { + projectKeys = append(projectKeys, strings.TrimSuffix(projectKey.PrivateKey, "\n")) + outputOptions.MultiLine = true + } + + var data []output.Data + data = append(data, projectKeys) + + dataMain := output.Table{ + Header: []string{"PublicKey"}, + Data: data, + } + if len(dataMain.Data) == 0 { - output.RenderInfo(fmt.Sprintf("No project-key for project '%s'", getProjectFlags.Project), outputOptions) - os.Exit(0) + outputOptions.Error = fmt.Sprintf("No project-key for project '%s'", cmdProjectName) } - output.RenderOutput(dataMain, outputOptions) + if projectKey.PrivateKey != "" { + dataMain.Header = append(dataMain.Header, "PrivateKey") + } + output.RenderOutput(dataMain, outputOptions) + return nil }, } diff --git a/cmd/list.go b/cmd/list.go index bd729ec4..76c26ccd 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -8,9 +8,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" - "github.com/uselagoon/lagoon-cli/internal/schema" "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/output" l "github.com/uselagoon/machinery/api/lagoon" @@ -66,13 +63,14 @@ var listDeployTargetsCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) - deploytargets, err := lagoon.ListDeployTargets(context.TODO(), lc) + deploytargets, err := l.ListDeployTargets(context.TODO(), lc) if err != nil { return err } @@ -94,6 +92,7 @@ var listDeployTargetsCmd = &cobra.Command{ returnNonEmptyString(fmt.Sprintf("%v", deploytarget.MonitoringConfig)), }) } + outputOptions.MultiLine = true output.RenderOutput(output.Table{ Header: []string{ "ID", @@ -239,10 +238,8 @@ var listVariablesCmd = &cobra.Command{ return validateTokenE(cmdLagoon) }, RunE: func(cmd *cobra.Command, args []string) error { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) + if err := requiredInputCheck("Project name", cmdProjectName); err != nil { + return err } reveal, err := cmd.Flags().GetBool("reveal") if err != nil { @@ -253,17 +250,18 @@ var listVariablesCmd = &cobra.Command{ return err } current := lagoonCLIConfig.Current - lc := client.New( + token := lagoonCLIConfig.Lagoons[current].Token + lc := lclient.New( lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, lagoonCLIVersion, + lagoonCLIConfig.Lagoons[current].Version, + &token, debug) - in := &schema.EnvVariableByProjectEnvironmentNameInput{ + in := &ls.EnvVariableByProjectEnvironmentNameInput{ Project: cmdProjectName, Environment: cmdProjectEnvironment, } - envvars, err := lagoon.GetEnvVariablesByProjectEnvironmentName(context.TODO(), in, lc) + envvars, err := l.GetEnvVariablesByProjectEnvironmentName(context.TODO(), in, lc) if err != nil { return err } @@ -280,6 +278,7 @@ var listVariablesCmd = &cobra.Command{ env = append(env, returnNonEmptyString(fmt.Sprintf("%v", envvar.Name))) if reveal { env = append(env, fmt.Sprintf("%v", envvar.Value)) + outputOptions.MultiLine = true } data = append(data, env) } diff --git a/cmd/users.go b/cmd/users.go index 343c8cf7..b9d9da6e 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -260,9 +260,8 @@ var getUserKeysCmd = &cobra.Command{ if err != nil { return err } - if userEmail == "" { - fmt.Println("Missing arguments: Email address is not defined") - return nil + if err := requiredInputCheck("Email address", userEmail); err != nil { + return err } current := lagoonCLIConfig.Current @@ -274,7 +273,9 @@ var getUserKeysCmd = &cobra.Command{ &token, debug) userKeys, err := l.GetUserSSHKeysByEmail(context.TODO(), userEmail, lc) - handleError(err) + if err != nil { + return err + } if len(userKeys.SSHKeys) == 0 { output.RenderInfo(fmt.Sprintf("No SSH keys for user '%s'", strings.ToLower(userEmail)), outputOptions) return nil @@ -296,6 +297,7 @@ var getUserKeysCmd = &cobra.Command{ Data: data, } + outputOptions.MultiLine = true output.RenderOutput(dataMain, outputOptions) return nil }, @@ -360,7 +362,7 @@ var getAllUserKeysCmd = &cobra.Command{ Header: []string{"ID", "Email", "Name", "Type", "Value"}, Data: data, } - + outputOptions.MultiLine = true output.RenderOutput(dataMain, outputOptions) return nil }, diff --git a/go.mod b/go.mod index 19c26488..eb9bd445 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 - github.com/uselagoon/machinery v0.0.20 + github.com/uselagoon/machinery v0.0.21-0.20240418053856-64532c59a80d golang.org/x/crypto v0.21.0 golang.org/x/term v0.18.0 gopkg.in/yaml.v3 v3.0.1 @@ -40,4 +40,4 @@ require ( golang.org/x/sys v0.18.0 // indirect ) -// replace github.com/uselagoon/machinery => ../machinery +//replace github.com/uselagoon/machinery => ../machinery diff --git a/go.sum b/go.sum index ab7a4eb7..189f9337 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/uselagoon/machinery v0.0.20 h1:4pGGX/Y5UwbT86TU9vaP7QyjGk8wvikUVDvkTpesvbs= github.com/uselagoon/machinery v0.0.20/go.mod h1:NbgtEofjK2XY0iUpk9aMYazIo+W/NI56+UF72jv8zVY= +github.com/uselagoon/machinery v0.0.21-0.20240418053856-64532c59a80d h1:tBLPNkjps1mBkCupbvaWsko+ZuQO157RnWLTWON044k= +github.com/uselagoon/machinery v0.0.21-0.20240418053856-64532c59a80d/go.mod h1:NbgtEofjK2XY0iUpk9aMYazIo+W/NI56+UF72jv8zVY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql b/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql deleted file mode 100644 index f24d0450..00000000 --- a/internal/lagoon/client/_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql +++ /dev/null @@ -1,10 +0,0 @@ -query ( - $input: EnvVariableByProjectEnvironmentNameInput! -){ - getEnvVariablesByProjectEnvironmentName(input: $input) { - id - name - value - scope - } -} diff --git a/internal/lagoon/client/query.go b/internal/lagoon/client/query.go index 2957d21c..12327ede 100644 --- a/internal/lagoon/client/query.go +++ b/internal/lagoon/client/query.go @@ -213,22 +213,3 @@ func (c *Client) ListDeployTargets( Response: deploytargets, }) } - -// GetEnvVariablesByProjectEnvironmentName queries the Lagoon API for a envvars by project environment and unmarshals the response. -func (c *Client) GetEnvVariablesByProjectEnvironmentName( - ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, envkeyvalue *[]schema.EnvKeyValue) error { - - req, err := c.newRequest("_lgraphql/variables/getEnvVariablesByProjectEnvironmentName.graphql", - map[string]interface{}{ - "input": in, - }) - if err != nil { - return err - } - - return c.client.Run(ctx, req, &struct { - Response *[]schema.EnvKeyValue `json:"getEnvVariablesByProjectEnvironmentName"` - }{ - Response: envkeyvalue, - }) -} diff --git a/internal/lagoon/variables.go b/internal/lagoon/variables.go index e07c7be4..f20171aa 100644 --- a/internal/lagoon/variables.go +++ b/internal/lagoon/variables.go @@ -9,7 +9,6 @@ import ( type Variables interface { AddOrUpdateEnvVariableByName(ctx context.Context, in *schema.EnvVariableByNameInput, envvar *schema.UpdateEnvVarResponse) error DeleteEnvVariableByName(ctx context.Context, in *schema.DeleteEnvVariableByNameInput, envvar *schema.DeleteEnvVarResponse) error - GetEnvVariablesByProjectEnvironmentName(ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, envvar *[]schema.EnvKeyValue) error } func AddOrUpdateEnvVariableByName(ctx context.Context, in *schema.EnvVariableByNameInput, v Variables) (*schema.UpdateEnvVarResponse, error) { @@ -21,9 +20,3 @@ func DeleteEnvVariableByName(ctx context.Context, in *schema.DeleteEnvVariableBy envvar := schema.DeleteEnvVarResponse{} return &envvar, v.DeleteEnvVariableByName(ctx, in, &envvar) } - -// ListEnvVars gets info of envvars in lagoon. -func GetEnvVariablesByProjectEnvironmentName(ctx context.Context, in *schema.EnvVariableByProjectEnvironmentNameInput, v Variables) (*[]schema.EnvKeyValue, error) { - envvar := []schema.EnvKeyValue{} - return &envvar, v.GetEnvVariablesByProjectEnvironmentName(ctx, in, &envvar) -} diff --git a/internal/schema/envVar.go b/internal/schema/envVar.go index abd14cc9..db591e99 100644 --- a/internal/schema/envVar.go +++ b/internal/schema/envVar.go @@ -35,11 +35,6 @@ type DeleteEnvVariableByNameInput struct { Name string `json:"name"` } -type EnvVariableByProjectEnvironmentNameInput struct { - Environment string `json:"environment,omitempty"` - Project string `json:"project"` -} - type UpdateEnvVarResponse struct { EnvKeyValue } diff --git a/pkg/lagoon/projects/main.go b/pkg/lagoon/projects/main.go index b6598638..566e2de1 100644 --- a/pkg/lagoon/projects/main.go +++ b/pkg/lagoon/projects/main.go @@ -3,8 +3,6 @@ package projects import ( "encoding/json" "fmt" - "strings" - "github.com/uselagoon/lagoon-cli/internal/lagoon" "github.com/uselagoon/lagoon-cli/pkg/api" "github.com/uselagoon/lagoon-cli/pkg/graphql" @@ -21,7 +19,6 @@ type Projects struct { type Client interface { ListAllProjects() ([]byte, error) ListProjectVariables(string, bool) ([]byte, error) - GetProjectKey(string, bool) ([]byte, error) GetProjectInfo(string) ([]byte, error) DeleteProject(string) ([]byte, error) AddProject(string, string) ([]byte, error) @@ -222,54 +219,3 @@ func processProjectUpdate(projectByName []byte, jsonPatch string) (api.UpdatePro } return projectUpdate, nil } - -// GetProjectKey will get basic info about a project -func (p *Projects) GetProjectKey(projectName string, revealValue bool) ([]byte, error) { - // get project info from lagoon - project := api.Project{ - Name: projectName, - } - keyFragment := `fragment Project on Project { - publicKey - }` - if revealValue { - keyFragment = `fragment Project on Project { - privateKey - publicKey - }` - } - projectByName, err := p.api.GetProjectByName(project, keyFragment) - if err != nil { - return []byte(""), err - } - returnResult, err := processProjectKey(projectByName, revealValue) - if err != nil { - return []byte(""), err - } - return returnResult, nil -} - -func processProjectKey(projectByName []byte, revealValue bool) ([]byte, error) { - var project api.Project - err := json.Unmarshal([]byte(projectByName), &project) - if err != nil { - return []byte(""), err - } - // get the key, but strip the newlines we don't need - projectData := []string{ - strings.TrimSuffix(project.PublicKey, "\n"), - } - if revealValue { - projectData = append(projectData, strings.TrimSuffix(project.PrivateKey, "\n")) - } - var data []output.Data - data = append(data, projectData) - dataMain := output.Table{ - Header: []string{"PublicKey"}, - Data: data, - } - if revealValue { - dataMain.Header = append(dataMain.Header, "PrivateKey") - } - return json.Marshal(dataMain) -} diff --git a/pkg/output/main.go b/pkg/output/main.go index 2465336d..e40e24f0 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/jedib0t/go-pretty/v6/table" - "github.com/jedib0t/go-pretty/v6/text" "github.com/logrusorgru/aurora" ) @@ -22,12 +21,13 @@ type Data []string // Options . type Options struct { - Header bool - CSV bool - JSON bool - Pretty bool - Debug bool - Error string + Header bool + CSV bool + JSON bool + Pretty bool + Debug bool + Error string + MultiLine bool } // Result . @@ -151,8 +151,17 @@ func RenderOutput(data Table, opts Options) { t.Style().Options = table.OptionsNoBordersAndSeparators t.Style().Box.PaddingLeft = "" // trim left space t.Style().Box.PaddingRight = "\t" // pad right with tab - t.SuppressTrailingSpaces() // suppress the trailing spaces - t.SetColumnConfigs([]table.ColumnConfig{{Align: text.AlignLeft}}) + if !opts.MultiLine { + t.SuppressTrailingSpaces() // suppress the trailing spaces if not multiline + } + if opts.MultiLine { + // stops multiline values bleeding into other columns + t.SetColumnConfigs([]table.ColumnConfig{ + {Name: "Value", WidthMax: 75}, // Set specific width for "Value" column if multiline + {Name: "Token", WidthMax: 50}, // Set specific width for "Token" column if multiline + }) + } + if opts.CSV { t.RenderCSV() return