diff --git a/cmd/export/export.go b/cmd/export/export.go index de39349f..a2eebc73 100644 --- a/cmd/export/export.go +++ b/cmd/export/export.go @@ -1,6 +1,7 @@ package export import ( + "errors" "fmt" "io" "log" @@ -16,7 +17,7 @@ import ( const envVarExportPrefix = "VKV_EXPORT_" -var errInvalidFlagCombination = fmt.Errorf("invalid flag combination specified") +var errInvalidFlagCombination = errors.New("invalid flag combination specified") // exportOptions holds all available commandline options. type exportOptions struct { @@ -41,6 +42,7 @@ type exportOptions struct { } // NewExportCmd export subcommand. +// //nolint:lll func NewExportCmd(writer io.Writer, vaultClient *vault.Vault) *cobra.Command { var err error @@ -134,7 +136,7 @@ func (o *exportOptions) validateFlags() error { case (o.OnlyKeys && o.ShowValues), (o.OnlyPaths && o.ShowValues), (o.OnlyKeys && o.OnlyPaths): return errInvalidFlagCombination case o.EnginePath == "" && o.Path == "": - return fmt.Errorf("no KV-paths given. Either --engine-path / -e or --path / -p needs to be specified") + return errors.New("no KV-paths given. Either --engine-path / -e or --path / -p needs to be specified") case true: switch strings.ToLower(o.FormatString) { case "yaml", "yml": diff --git a/cmd/imp/import.go b/cmd/imp/import.go index cfd65f5f..c9ef6884 100644 --- a/cmd/imp/import.go +++ b/cmd/imp/import.go @@ -1,6 +1,7 @@ package imp import ( + "errors" "fmt" "io" "log" @@ -16,7 +17,7 @@ import ( const envVarImportPrefix = "VKV_IMPORT_" -var errInvalidFlagCombination = fmt.Errorf("invalid flag combination specified") +var errInvalidFlagCombination = errors.New("invalid flag combination specified") type importOptions struct { Force bool `env:"FORCE"` @@ -31,7 +32,7 @@ type importOptions struct { } // NewImportCmd import subcommand. -//nolint: cyclop, gocognit +// nolint: cyclop, gocognit func NewImportCmd(writer io.Writer, vaultClient *vault.Vault) *cobra.Command { var err error @@ -127,11 +128,11 @@ func (o *importOptions) parseEnvs() error { return nil } -//nolint: cyclop +// nolint: cyclop func (o *importOptions) validateFlags(args []string) error { switch { case len(args) == 0 && o.Path == "": - return fmt.Errorf("no KV-path given, -path / -p needs to be specified") + return errors.New("no KV-path given, -path / -p needs to be specified") case o.Force && o.DryRun: return fmt.Errorf("%w: %s", errInvalidFlagCombination, "cannot specify both --force and --dry-run") case o.Silent && o.DryRun: @@ -165,7 +166,7 @@ func (o *importOptions) getInput(cmd *cobra.Command) ([]byte, error) { fmt.Fprintln(o.writer, "reading secrets from STDIN") if len(out) == 0 { - return nil, fmt.Errorf("no input found, perhaps the piped command failed or specified file is empty") + return nil, errors.New("no input found, perhaps the piped command failed or specified file is empty") } return out, nil diff --git a/cmd/root.go b/cmd/root.go index 48a8335c..86b6c14f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "io" "os" @@ -17,6 +18,7 @@ import ( ) // NewRootCmd vkv root command. +// //nolint:cyclop func NewRootCmd(v string, writer io.Writer) *cobra.Command { cmd := &cobra.Command{ @@ -56,7 +58,7 @@ func NewRootCmd(v string, writer io.Writer) *cobra.Command { } } default: - return fmt.Errorf("invalid value for VKV_MODE") + return errors.New("invalid value for VKV_MODE") } return cmd.Help() diff --git a/cmd/server/server.go b/cmd/server/server.go index 0080dafb..7fb5dcbd 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -2,7 +2,6 @@ package server import ( "bytes" - "fmt" "io" "log" "path" @@ -40,6 +39,7 @@ func defaultServerOptions() *serverOptions { } // NewServerCmd export subcommand. +// //nolint:lll func NewServerCmd(writer io.Writer, vaultClient *vault.Vault) *cobra.Command { var err error @@ -156,7 +156,7 @@ func (o *serverOptions) serve() error { c.Data(200, "text/plain", o.readSecrets()) }) - return r.Run(fmt.Sprintf(":%s", o.Port)) + return r.Run(o.Port) } func (o *serverOptions) readSecrets() []byte { diff --git a/cmd/snapshot/snapshot_restore.go b/cmd/snapshot/snapshot_restore.go index 542dc2c6..bd5bdfe3 100644 --- a/cmd/snapshot/snapshot_restore.go +++ b/cmd/snapshot/snapshot_restore.go @@ -72,7 +72,7 @@ func (o *snapshotRestoreOptions) parseEnvs() error { return nil } -//nolint: cyclop +// nolint: cyclop func (o *snapshotRestoreOptions) restoreSecrets(v *vault.Vault, source string) error { return filepath.Walk(source, func(p string, info os.FileInfo, err error) error { if err != nil { @@ -119,6 +119,7 @@ func (o *snapshotRestoreOptions) restoreSecrets(v *vault.Vault, source string) e // create engine v.Client.SetNamespace(ns) + if err := v.EnableKV2EngineErrorIfNotForced(true, engine); err != nil { return err } diff --git a/cmd/snapshot/snapshot_save.go b/cmd/snapshot/snapshot_save.go index 7fe6f1b8..9c8b5f9f 100644 --- a/cmd/snapshot/snapshot_save.go +++ b/cmd/snapshot/snapshot_save.go @@ -66,7 +66,7 @@ func newSnapshotSaveCmd(writer io.Writer, vaultClient *vault.Vault) *cobra.Comma return cmd } -//nolint: cyclop +// nolint: cyclop func (o *snapshotSaveOptions) backupKVEngines(v *vault.Vault, engines map[string][]string) error { for _, ns := range utils.SortMapKeys(utils.ToMapStringInterface(engines)) { nsDir := path.Join(o.Destination, ns) diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index 21ff306b..c476fdde 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -8,7 +8,7 @@ import ( ) // Run runs the given command and returns the output. -//nolint: gosec +// nolint: gosec func Run(cmd []string) ([]byte, error) { var stdout, stderr bytes.Buffer diff --git a/pkg/printer/engine/engine_printer.go b/pkg/printer/engine/engine_printer.go index 02709b0a..c22404ce 100644 --- a/pkg/printer/engine/engine_printer.go +++ b/pkg/printer/engine/engine_printer.go @@ -1,6 +1,7 @@ package engine import ( + "errors" "fmt" "io" "os" @@ -29,7 +30,7 @@ var ( defaultWriter = os.Stdout // ErrInvalidFormat invalid output format. - ErrInvalidFormat = fmt.Errorf("invalid format (valid options: base, yaml, json, export, markdown)") + ErrInvalidFormat = errors.New("invalid format (valid options: base, yaml, json, export, markdown)") ) // Option list of available options for modifying the output. @@ -85,12 +86,12 @@ func NewPrinter(opts ...Option) *Printer { } // Out prints out engines. -//nolint: cyclop +// nolint: cyclop func (p *Printer) Out(engines map[string][]string) error { engineList := p.buildEngineList(engines) if len(engineList) == 0 { - return fmt.Errorf("no engines found") + return errors.New("no engines found") } if p.Regex != "" { diff --git a/pkg/printer/namespace/namespace_printer.go b/pkg/printer/namespace/namespace_printer.go index 613a029b..d51ec4fa 100644 --- a/pkg/printer/namespace/namespace_printer.go +++ b/pkg/printer/namespace/namespace_printer.go @@ -1,6 +1,7 @@ package namespace import ( + "errors" "fmt" "io" "os" @@ -29,7 +30,7 @@ var ( defaultWriter = os.Stdout // ErrInvalidFormat invalid output format. - ErrInvalidFormat = fmt.Errorf("invalid format (valid options: base, yaml, json, export, markdown)") + ErrInvalidFormat = errors.New("invalid format (valid options: base, yaml, json, export, markdown)") ) // Option list of available options for modifying the output. @@ -77,12 +78,12 @@ func NewPrinter(opts ...Option) *Printer { } // Out prits out namespaces in various formats. -//nolint: cyclop +// nolint: cyclop func (p *Printer) Out(ns map[string][]string) error { nsList := p.buildNamespaceList(ns) if len(ns) == 0 { - return fmt.Errorf("no namespaces found") + return errors.New("no namespaces found") } if p.Regex != "" { diff --git a/pkg/printer/secret/markdown.go b/pkg/printer/secret/markdown.go index 0a720cb2..24710d83 100644 --- a/pkg/printer/secret/markdown.go +++ b/pkg/printer/secret/markdown.go @@ -22,7 +22,7 @@ func (p *Printer) printMarkdownTable(enginePath string, secrets map[string]inter return nil } -//nolint: gocognit, nestif, cyclop +// nolint: gocognit, nestif, cyclop func (p *Printer) buildMarkdownTable(enginePath string, secrets map[string]interface{}) ([]string, [][]string) { data := [][]string{} headers := []string{} @@ -83,6 +83,7 @@ func (p *Printer) buildMarkdownTable(enginePath string, secrets map[string]inter if p.showVersion { d = append(d, "") } + if p.showMetadata { d = append(d, "") } diff --git a/pkg/printer/secret/secret_printer.go b/pkg/printer/secret/secret_printer.go index 1aa9c286..3c59af35 100644 --- a/pkg/printer/secret/secret_printer.go +++ b/pkg/printer/secret/secret_printer.go @@ -1,7 +1,7 @@ package secret import ( - "fmt" + "errors" "io" "log" "os" @@ -46,7 +46,7 @@ var ( defaultWriter = os.Stdout // ErrInvalidFormat invalid output format. - ErrInvalidFormat = fmt.Errorf("invalid format (valid options: base, yaml, json, export, markdown)") + ErrInvalidFormat = errors.New("invalid format (valid options: base, yaml, json, export, markdown)") ) // Option list of available options for modifying the output. @@ -180,7 +180,7 @@ func (p *Printer) WithOption(opt Option) { } // Out prints out the secrets according all configured options. -//nolint: cyclop +// nolint: cyclop func (p *Printer) Out(enginePath string, secrets map[string]interface{}) error { for k, v := range secrets { if !p.showValues { diff --git a/pkg/testutils/testutils.go b/pkg/testutils/testutils.go index 1a3c0080..1bfd8b8a 100644 --- a/pkg/testutils/testutils.go +++ b/pkg/testutils/testutils.go @@ -2,7 +2,6 @@ package testutils import ( "context" - "fmt" "os" "time" @@ -13,7 +12,7 @@ import ( var ( vaultVersion = "latest" - image = fmt.Sprintf("hashicorp/vault:%s", vaultVersion) + image = "hashicorp/vault:" + vaultVersion envs = map[string]string{} token = "root" ) @@ -37,7 +36,7 @@ func StartTestContainer() (*TestContainer, error) { // use OSS image per default, if license is available use enterprise if license, ok := os.LookupEnv("VAULT_LICENSE"); ok { envs["VAULT_LICENSE"] = license - image = fmt.Sprintf("hashicorp/vault-enterprise:%s", vaultVersion) + image = "hashicorp/vault-enterprise" + vaultVersion } req := testcontainers.ContainerRequest{ @@ -70,7 +69,7 @@ func StartTestContainer() (*TestContainer, error) { return &TestContainer{ Container: c, ctx: ctx, - URI: fmt.Sprintf("http://127.0.0.1:%s", mappedPort.Port()), + URI: "http://127.0.0.1:" + mappedPort.Port(), Token: token, }, nil } diff --git a/pkg/vault/client.go b/pkg/vault/client.go index b9b3241c..af3d3a94 100644 --- a/pkg/vault/client.go +++ b/pkg/vault/client.go @@ -1,6 +1,7 @@ package vault import ( + "errors" "fmt" "os" "strings" @@ -19,7 +20,7 @@ func NewDefaultClient() (*Vault, error) { // error if no VAULT_ADDR exported _, ok := os.LookupEnv("VAULT_ADDR") if !ok { - return nil, fmt.Errorf("VAULT_ADDR required but not set") + return nil, errors.New("VAULT_ADDR required but not set") } // get vault token @@ -40,7 +41,7 @@ func NewDefaultClient() (*Vault, error) { // if toke is still empty, error if vaultToken == "" { - return nil, fmt.Errorf("VKV_LOGIN_COMMAND or VAULT_TOKEN required but not set") + return nil, errors.New("VKV_LOGIN_COMMAND or VAULT_TOKEN required but not set") } // read all other vault env vars diff --git a/pkg/vault/engine.go b/pkg/vault/engine.go index 4b3b8338..caf6fa09 100644 --- a/pkg/vault/engine.go +++ b/pkg/vault/engine.go @@ -99,7 +99,7 @@ func (v *Vault) ListKVSecretEngines(ns string) ([]string, error) { return nil, fmt.Errorf("cannot get type of engine: %s", k) } - if fmt.Sprintf("%v", t) == "kv" { + if fmt.Sprintf("%v", t) == "kv" || fmt.Sprintf("%v", t) == "generic" { engineList = append(engineList, k) } } diff --git a/pkg/vault/kv.go b/pkg/vault/kv.go index 650c5c56..a86aad72 100644 --- a/pkg/vault/kv.go +++ b/pkg/vault/kv.go @@ -1,6 +1,7 @@ package vault import ( + "errors" "fmt" "log" "path" @@ -9,7 +10,7 @@ import ( "github.com/FalcoSuessgott/vkv/pkg/utils" ) -//nolint: gosec +// nolint: gosec const ( kvv1ReadWriteSecretsPath = "%s/%s" kvv1ListSecretsPath = "%s/%s" @@ -24,7 +25,7 @@ const ( type Secrets map[string]interface{} // ListRecursive returns secrets to a path recursive. -//nolint: cyclop +// nolint: cyclop func (v *Vault) ListRecursive(rootPath, subPath string, skipErrors bool) (*Secrets, error) { s := make(Secrets) @@ -105,7 +106,7 @@ func (v *Vault) ListKeys(rootPath, subPath string) ([]string, error) { return nil, fmt.Errorf("no keys found in \"%s\"", path.Join(rootPath, subPath)) } -// IsKVv1 returns true if the current path is a KVv2 Engine. +// IsKVv1 returns true if the current path is a KVv1 Engine. func (v *Vault) IsKVv1(rootPath string) (bool, error) { data, err := v.Client.Logical().Read(fmt.Sprintf(mountDetailsPath, rootPath)) if err != nil { @@ -113,15 +114,18 @@ func (v *Vault) IsKVv1(rootPath string) (bool, error) { } if data == nil { - return false, fmt.Errorf("cannot lookup mount type") + return false, errors.New("cannot lookup mount type") } - if opt, ok := data.Data["options"]; ok { - if version, ok := opt.(map[string]interface{})["version"]; ok { - //nolint: forcetypeassert - if version.(string) == "1" { - return true, nil - } + // early versions of Vaults KV engine are of type "generic" + if data.Data["type"] == "generic" { + return true, nil + } + + if opts, ok := data.Data["options"].(map[string]interface{}); ok { + //nolint: forcetypeassert + if opts["version"].(string) == "1" { + return true, nil } } diff --git a/pkg/vault/kv_test.go b/pkg/vault/kv_test.go index a916f9d3..34a5da0f 100644 --- a/pkg/vault/kv_test.go +++ b/pkg/vault/kv_test.go @@ -69,7 +69,6 @@ func (s *VaultSuite) TestListRecursive() { for _, tc := range testCases { s.Run(tc.name, func() { // write secrets - if tc.v1 { require.NoError(s.Suite.T(), s.client.EnableKV1Engine(tc.rootPath)) } else { diff --git a/pkg/vault/namespace_test.go b/pkg/vault/namespace_test.go index a20a19dd..64329ee8 100644 --- a/pkg/vault/namespace_test.go +++ b/pkg/vault/namespace_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" ) -//nolint: errcheck +// nolint: errcheck func (s *VaultSuite) TestNamespaces() { testCases := []struct { name string diff --git a/pkg/vault/namespaces.go b/pkg/vault/namespaces.go index a214351a..c991f70d 100644 --- a/pkg/vault/namespaces.go +++ b/pkg/vault/namespaces.go @@ -30,7 +30,7 @@ func (v *Vault) ListAllNamespaces(ns string) (Namespaces, error) { return m, nil } -//nolint: godox +// nolint: godox func (v *Vault) namespaceIterator(ns string, res *Namespaces) error { nsList, err := v.ListNamespaces(ns) if err != nil {