Skip to content

Commit

Permalink
Add galasactl secrets get command and formatters (#301)
Browse files Browse the repository at this point in the history
* feat: Add galasactl secrets get command and formatters

Signed-off-by: Eamonn Mansour <[email protected]>

* feat: Add validation to secrets

Signed-off-by: Eamonn Mansour <[email protected]>

* Empty commit to kick off build

Signed-off-by: Eamonn Mansour <[email protected]>

---------

Signed-off-by: Eamonn Mansour <[email protected]>
  • Loading branch information
eamansour authored Oct 31, 2024
1 parent 6e7fe65 commit ba08e28
Show file tree
Hide file tree
Showing 18 changed files with 1,711 additions and 5 deletions.
84 changes: 84 additions & 0 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,90 @@
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secrets/secretsGet_test.go": [
{
"hashed_secret": "11747ed2a3904f82931baf592443772259ea8dc1",
"is_secret": false,
"is_verified": false,
"line_number": 25,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "679d55ddc3c3d0f6ea2d11275a5d084669c98d56",
"is_secret": false,
"is_verified": false,
"line_number": 62,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "3b938c1150a71e71e5f1ffeadbe6475f0f6a2e36",
"is_secret": false,
"is_verified": false,
"line_number": 122,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "2dfbe3ec00a96d6f711d9a70f78be17f6fd574ca",
"is_secret": false,
"is_verified": false,
"line_number": 284,
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secretsformatter/GalasaSecret.go": [
{
"hashed_secret": "1949c4c92eb313637b3b6f654f5cce42df0dde88",
"is_secret": false,
"is_verified": false,
"line_number": 62,
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secretsformatter/summaryFormatter.go": [
{
"hashed_secret": "4d55af37dbbb6a42088d917caa1ca25428ec42c9",
"is_secret": false,
"is_verified": false,
"line_number": 44,
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secretsformatter/summaryFormatter_test.go": [
{
"hashed_secret": "11747ed2a3904f82931baf592443772259ea8dc1",
"is_secret": false,
"is_verified": false,
"line_number": 20,
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secretsformatter/yamlFormatter.go": [
{
"hashed_secret": "4d55af37dbbb6a42088d917caa1ca25428ec42c9",
"is_secret": false,
"is_verified": false,
"line_number": 34,
"type": "Secret Keyword",
"verified_result": null
}
],
"pkg/secretsformatter/yamlFormatter_test.go": [
{
"hashed_secret": "679d55ddc3c3d0f6ea2d11275a5d084669c98d56",
"is_secret": false,
"is_verified": false,
"line_number": 29,
"type": "Secret Keyword",
"verified_result": null
}
]
},
"version": "0.13.1+ibm.62.dss",
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,31 @@ galasactl resources delete -f my_resources.yaml

For a complete list of supported parameters see [here](./docs/generated/galasactl_resources_delete.md).

## secrets get

This command retrieves a list of secrets stored in the Galasa Ecosystem's credentials store. The retrieved secrets can be displayed in different formats, including `summary` and `yaml` formats, based on the value provided by the `--format` flag. If `--format` is not provided, secrets will be displayed in the `summary` format by default.

### Examples

All secrets stored in a Galasa Ecosystem can be retrieved using the following command:

```
galasactl secrets get
```

To get a specific secret named `SYSTEM1`, the `--name` flag can be provided as follows:

```
galasactl secrets get --name SYSTEM1
```

To display a secret in a different format, like YAML, the `--format` flag can be provided:

```
galasactl secrets get --name SYSTEM1 --format yaml
```

For a complete list of supported parameters see [here](./docs/generated/galasactl_secrets_get.md).

## secrets delete

Expand Down
12 changes: 12 additions & 0 deletions docs/generated/errors-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ The `galasactl` tool can generate the following errors:
- GAL1171E: An attempt to delete a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1172E: Invalid secret name provided. The name provided with the --name flag cannot be empty or contain spaces, and must only contain characters in the Latin-1 character set.
- GAL1173E: An attempt to delete a secret named '{}' failed. Sending the delete request to the Galasa service failed. Cause is {}
- GAL1174E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server.
- GAL1175E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server could not be read. Cause: {}
- GAL1176E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in a valid json format. Cause: '{}'
- GAL1177E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are: '{}'
- GAL1178E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1179E: An attempt to get a secret named '{}' failed. Sending the get request to the Galasa service failed. Cause is {}
- GAL1180E: Failed to get secrets. Unexpected http status code {} received from the server.
- GAL1181E: Failed to get secrets. Unexpected http status code {} received from the server. Error details from the server could not be read. Cause: {}
- GAL1182E: Failed to get secrets. Unexpected http status code {} received from the server. Error details from the server are not in a valid json format. Cause: '{}'
- GAL1183E: Failed to get secrets. Unexpected http status code {} received from the server. Error details from the server are: '{}'
- GAL1184E: Failed to get secrets. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1185E: Failed to get secrets. Sending the get request to the Galasa service failed. Cause is {}
- GAL1225E: Failed to open file '{}' cause: {}. Check that this file exists, and that you have read permissions.
- GAL1226E: Internal failure. Contents of gzip could be read, but not decoded. New gzip reader failed: file: {} error: {}
- GAL1227E: Internal failure. Contents of gzip could not be decoded. {} error: {}
Expand Down
1 change: 1 addition & 0 deletions docs/generated/galasactl_secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ The parent command for operations to manipulate secrets in the Galasa service's

* [galasactl](galasactl.md) - CLI for Galasa
* [galasactl secrets delete](galasactl_secrets_delete.md) - Deletes a secret from the credentials store
* [galasactl secrets get](galasactl_secrets_get.md) - Get secrets from the credentials store

32 changes: 32 additions & 0 deletions docs/generated/galasactl_secrets_get.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## galasactl secrets get

Get secrets from the credentials store

### Synopsis

Get a list of secrets or a specific secret from the credentials store

```
galasactl secrets get [flags]
```

### Options

```
--format string the output format of the returned secrets. Supported formats are: 'summary', 'yaml'. (default "summary")
-h, --help Displays the options for the 'secrets get' command.
--name string An optional flag that identifies the secret to be retrieved.
```

### Options inherited from parent commands

```
-b, --bootstrap string Bootstrap URL. Should start with 'http://' or 'file://'. If it starts with neither, it is assumed to be a fully-qualified path. If missing, it defaults to use the 'bootstrap.properties' file in your GALASA_HOME. Example: http://example.com/bootstrap, file:///user/myuserid/.galasa/bootstrap.properties , file://C:/Users/myuserid/.galasa/bootstrap.properties
--galasahome string Path to a folder where Galasa will read and write files and configuration settings. The default is '${HOME}/.galasa'. This overrides the GALASA_HOME environment variable which may be set instead.
-l, --log string File to which log information will be sent. Any folder referred to must exist. An existing file will be overwritten. Specify "-" to log to stderr. Defaults to not logging.
```

### SEE ALSO

* [galasactl secrets](galasactl_secrets.md) - Manage secrets stored in the Galasa service's credentials store

7 changes: 7 additions & 0 deletions pkg/cmd/commandCollection.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const (
COMMAND_NAME_RESOURCES_UPDATE = "resources update"
COMMAND_NAME_RESOURCES_DELETE = "resources delete"
COMMAND_NAME_SECRETS = "secrets"
COMMAND_NAME_SECRETS_GET = "secrets get"
COMMAND_NAME_SECRETS_DELETE = "secrets delete"
COMMAND_NAME_USERS = "users"
COMMAND_NAME_USERS_GET = "users get"
Expand Down Expand Up @@ -385,16 +386,22 @@ func (commands *commandCollectionImpl) addSecretsCommands(factory spi.Factory, r

var err error
var secretsCommand spi.GalasaCommand
var secretsGetCommand spi.GalasaCommand
var secretsDeleteCommand spi.GalasaCommand

secretsCommand, err = NewSecretsCmd(rootCommand)

if err == nil {
secretsGetCommand, err = NewSecretsGetCommand(factory, secretsCommand, rootCommand)
}

if err == nil {
secretsDeleteCommand, err = NewSecretsDeleteCommand(factory, secretsCommand, rootCommand)
}

if err == nil {
commands.commandMap[secretsCommand.Name()] = secretsCommand
commands.commandMap[secretsGetCommand.Name()] = secretsGetCommand
commands.commandMap[secretsDeleteCommand.Name()] = secretsDeleteCommand
}

Expand Down
150 changes: 150 additions & 0 deletions pkg/cmd/secretsGet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright contributors to the Galasa project
*
* SPDX-License-Identifier: EPL-2.0
*/
package cmd

import (
"log"

"github.com/galasa-dev/cli/pkg/api"
"github.com/galasa-dev/cli/pkg/galasaapi"
"github.com/galasa-dev/cli/pkg/secrets"
"github.com/galasa-dev/cli/pkg/spi"
"github.com/galasa-dev/cli/pkg/utils"
"github.com/spf13/cobra"
)

type SecretsGetCmdValues struct {
outputFormat string
}

type SecretsGetCommand struct {
values *SecretsGetCmdValues
cobraCommand *cobra.Command
}

// ------------------------------------------------------------------------------------------------
// Constructors methods
// ------------------------------------------------------------------------------------------------
func NewSecretsGetCommand(
factory spi.Factory,
secretsGetCommand spi.GalasaCommand,
rootCmd spi.GalasaCommand,
) (spi.GalasaCommand, error) {

cmd := new(SecretsGetCommand)

err := cmd.init(factory, secretsGetCommand, rootCmd)
return cmd, err
}

// ------------------------------------------------------------------------------------------------
// Public methods
// ------------------------------------------------------------------------------------------------
func (cmd *SecretsGetCommand) Name() string {
return COMMAND_NAME_SECRETS_GET
}

func (cmd *SecretsGetCommand) CobraCommand() *cobra.Command {
return cmd.cobraCommand
}

func (cmd *SecretsGetCommand) Values() interface{} {
return cmd.values
}

// ------------------------------------------------------------------------------------------------
// Private methods
// ------------------------------------------------------------------------------------------------
func (cmd *SecretsGetCommand) init(factory spi.Factory, secretsCommand spi.GalasaCommand, rootCmd spi.GalasaCommand) error {
var err error

cmd.values = &SecretsGetCmdValues{}
cmd.cobraCommand, err = cmd.createCobraCmd(factory, secretsCommand, rootCmd.Values().(*RootCmdValues))

return err
}

func (cmd *SecretsGetCommand) createCobraCmd(
factory spi.Factory,
secretsCommand spi.GalasaCommand,
rootCommandValues *RootCmdValues,
) (*cobra.Command, error) {

var err error

secretsCommandValues := secretsCommand.Values().(*SecretsCmdValues)
secretsGetCobraCmd := &cobra.Command{
Use: "get",
Short: "Get secrets from the credentials store",
Long: "Get a list of secrets or a specific secret from the credentials store",
Aliases: []string{COMMAND_NAME_SECRETS_GET},
RunE: func(cobraCommand *cobra.Command, args []string) error {
return cmd.executeSecretsGet(factory, secretsCommand.Values().(*SecretsCmdValues), rootCommandValues)
},
}

addSecretNameFlag(secretsGetCobraCmd, false, secretsCommandValues)

formatters := secrets.GetFormatterNamesAsString()
secretsGetCobraCmd.Flags().StringVar(&cmd.values.outputFormat, "format", "summary", "the output format of the returned secrets. Supported formats are: "+formatters+".")

secretsCommand.CobraCommand().AddCommand(secretsGetCobraCmd)

return secretsGetCobraCmd, err
}

func (cmd *SecretsGetCommand) executeSecretsGet(
factory spi.Factory,
secretsCmdValues *SecretsCmdValues,
rootCmdValues *RootCmdValues,
) error {

var err error
// Operations on the file system will all be relative to the current folder.
fileSystem := factory.GetFileSystem()

err = utils.CaptureLog(fileSystem, rootCmdValues.logFileName)

if err == nil {
rootCmdValues.isCapturingLogs = true

log.Println("Galasa CLI - Get secrets from the ecosystem")

env := factory.GetEnvironment()

var galasaHome spi.GalasaHome
galasaHome, err = utils.NewGalasaHome(fileSystem, env, rootCmdValues.CmdParamGalasaHomePath)
if err == nil {

var urlService *api.RealUrlResolutionService = new(api.RealUrlResolutionService)
var bootstrapData *api.BootstrapData
bootstrapData, err = api.LoadBootstrap(galasaHome, fileSystem, env, secretsCmdValues.bootstrap, urlService)
if err == nil {

var console = factory.GetStdOutConsole()

apiServerUrl := bootstrapData.ApiServerURL
log.Printf("The API server is at '%s'\n", apiServerUrl)

authenticator := factory.GetAuthenticator(
apiServerUrl,
galasaHome,
)

var apiClient *galasaapi.APIClient
apiClient, err = authenticator.GetAuthenticatedAPIClient()

byteReader := factory.GetByteReader()

if err == nil {
err = secrets.GetSecrets(secretsCmdValues.name, cmd.values.outputFormat, console, apiClient, byteReader)
}
}
}
}

return err
}
Loading

0 comments on commit ba08e28

Please sign in to comment.