From 7f147bd5bb7a79fc94e39b69969cef8b4c106de0 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Tue, 3 Dec 2019 14:38:30 +1100 Subject: [PATCH] need to be able to get a projects key for other usage --- cmd/get.go | 32 ++++++++++++++ docs/commands/lagoon_get.md | 1 + docs/commands/lagoon_get_project-key.md | 39 +++++++++++++++++ lagoon/projects/main.go | 58 +++++++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 docs/commands/lagoon_get_project-key.md diff --git a/cmd/get.go b/cmd/get.go index 6b43b65b..1f2ceaa4 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -136,9 +136,41 @@ var getEnvironmentCmd = &cobra.Command{ }, } +var getProjectKeyCmd = &cobra.Command{ + Use: "project-key", + Short: "Get a projects key", + Run: func(cmd *cobra.Command, args []string) { + getProjectFlags := parseGetFlags(*cmd.Flags()) + if getProjectFlags.Project == "" { + fmt.Println("Not enough arguments. Requires: project name") + cmd.Help() + os.Exit(1) + } + returnedJSON, err := projects.GetProjectKey(getProjectFlags.Project, revealValue) + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + var dataMain output.Table + err = json.Unmarshal([]byte(returnedJSON), &dataMain) + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + if len(dataMain.Data) == 0 { + output.RenderError("no data returned", outputOptions) + os.Exit(1) + } + output.RenderOutput(dataMain, outputOptions) + + }, +} + func init() { getCmd.AddCommand(getProjectCmd) getCmd.AddCommand(getDeploymentCmd) getCmd.AddCommand(getEnvironmentCmd) + getCmd.AddCommand(getProjectKeyCmd) + getProjectKeyCmd.Flags().BoolVarP(&revealValue, "reveal", "", false, "Reveal the variable values") getDeploymentCmd.Flags().StringVarP(&remoteID, "remoteid", "R", "", "The remote ID of the deployment") } diff --git a/docs/commands/lagoon_get.md b/docs/commands/lagoon_get.md index 170d7ab1..a7740fa9 100644 --- a/docs/commands/lagoon_get.md +++ b/docs/commands/lagoon_get.md @@ -34,4 +34,5 @@ Get info on a project, or deployment * [lagoon get deployment](lagoon_get_deployment.md) - Get build log by remote id * [lagoon get environment](lagoon_get_environment.md) - Details about an environment * [lagoon get project](lagoon_get_project.md) - Details about a project +* [lagoon get project-key](lagoon_get_project-key.md) - Get a projects key diff --git a/docs/commands/lagoon_get_project-key.md b/docs/commands/lagoon_get_project-key.md new file mode 100644 index 00000000..0636d107 --- /dev/null +++ b/docs/commands/lagoon_get_project-key.md @@ -0,0 +1,39 @@ +## lagoon get project-key + +Get a projects key + +### Synopsis + +Get a projects key + +``` +lagoon get project-key [flags] +``` + +### Options + +``` + -h, --help help for project-key + --reveal Reveal the variable values +``` + +### Options inherited from parent commands + +``` + --all-projects All projects (if supported) + -e, --environment string Specify an environment to use + --force Force (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + -i, --ssh-key string Specify a specific SSH key to use + --version Version information +``` + +### SEE ALSO + +* [lagoon get](lagoon_get.md) - Get info on a project, or deployment + diff --git a/lagoon/projects/main.go b/lagoon/projects/main.go index 53a3fc47..ff89553c 100644 --- a/lagoon/projects/main.go +++ b/lagoon/projects/main.go @@ -3,10 +3,12 @@ package projects import ( "encoding/json" "fmt" + "strings" "github.com/amazeeio/lagoon-cli/api" "github.com/amazeeio/lagoon-cli/graphql" "github.com/amazeeio/lagoon-cli/output" + "golang.org/x/crypto/ssh" ) // ListAllProjects will list all projects @@ -263,3 +265,59 @@ func processProjectUpdate(projectByName []byte, jsonPatch string) (api.UpdatePro } return projectUpdate, nil } + +// GetProjectKey will get basic info about a project +func GetProjectKey(projectName string, revealValue bool) ([]byte, error) { + // set up a lagoonapi client + lagoonAPI, err := graphql.LagoonAPI() + if err != nil { + return []byte(""), err + } + // get project info from lagoon + project := api.Project{ + Name: projectName, + } + keyFragment := `fragment Project on Project { + privateKey + }` + projectByName, err := lagoonAPI.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 + } + signer, err := ssh.ParsePrivateKey([]byte(project.PrivateKey)) + if err != nil { + fmt.Println("Error was:", err.Error()) + return []byte(""), err + } + publicKey := signer.PublicKey() + // get the key, but strip the newlines we don't need + projectData := []string{ + strings.TrimSuffix(string(ssh.MarshalAuthorizedKey(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) +}