From 3ab2d41c2f596e1fe5fa59c72a559514bcc91080 Mon Sep 17 00:00:00 2001 From: MOREV Mikhail Date: Fri, 10 Jan 2020 09:33:03 +0600 Subject: [PATCH] fix filepath.Walk abuse; rename recursive flag; minor fixes --- README.rst | 8 ++--- cmd/sops/main.go | 46 ++++++++++++++++++-------- cmd/sops/subcommand/publish/publish.go | 38 ++------------------- 3 files changed, 39 insertions(+), 53 deletions(-) diff --git a/README.rst b/README.rst index 87a81679b..4c597a33f 100644 --- a/README.rst +++ b/README.rst @@ -978,10 +978,10 @@ published to S3 and GCS, it will decrypt them and re-encrypt them using the You would deploy a file to S3 with a command like: ``sops publish s3/app.yaml`` -To publish all files in selected directory recursively, you need to specify ``--recurse`` flag. +To publish all files in selected directory recursively, you need to specify ``--recursive`` flag. If you don't want file extension to appear in destination secret path, use ``--omit-extensions`` -flag or same ``.sops.yaml`` option. +flag or ``omit_extensions: true`` in the destination rule in ``.sops.yaml``. Publishing to Vault ******************* @@ -997,8 +997,8 @@ configuring the client. ``vault_kv_mount_name`` is used if your Vault KV is mounted somewhere other than ``secret/``. ``vault_kv_version`` supports ``1`` and ``2``, with ``2`` being the default. -If destination secret path already exists in Vault and contains same data as source file, it will -be skipped. +If destination secret path already exists in Vault and contains same data as the source file, it +will be skipped. Below is an example of publishing to Vault (using token auth with a local dev instance of Vault). diff --git a/cmd/sops/main.go b/cmd/sops/main.go index c676480eb..83393af20 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -223,7 +223,7 @@ func main() { Usage: "Omit file extensions in destination path when publishing sops file to configured destinations", }, cli.BoolFlag{ - Name: "recurse", + Name: "recursive", Usage: "If source path is directory, publish all its content recursively", }, cli.BoolFlag{ @@ -242,20 +242,38 @@ func main() { if c.NArg() < 1 { return common.NewExitError("Error: no file specified", codes.NoFileSpecified) } - fileName := c.Args()[0] - err = publishcmd.Run(publishcmd.Opts{ - ConfigPath: configPath, - InputPath: fileName, - Cipher: aes.NewCipher(), - KeyServices: keyservices(c), - Interactive: !c.Bool("yes"), - OmitExtensions: c.Bool("omit-extensions"), - Recurse: c.Bool("recurse"), + path := c.Args()[0] + info, err := os.Stat(path) + if err != nil { + return err + } + if info.IsDir() && !c.Bool("recursive") { + return fmt.Errorf("can't operate on a directory without --recursive flag.") + } + err = filepath.Walk(path, func(subPath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + err = publishcmd.Run(publishcmd.Opts{ + ConfigPath: configPath, + InputPath: subPath, + Cipher: aes.NewCipher(), + KeyServices: keyservices(c), + InputStore: inputStore(c, subPath), + Interactive: !c.Bool("yes"), + OmitExtensions: c.Bool("omit-extensions"), + }) + if cliErr, ok := err.(*cli.ExitError); ok && cliErr != nil { + return cliErr + } else if err != nil { + return common.NewExitError(err, codes.ErrorGeneric) + } + } + return nil }) - if cliErr, ok := err.(*cli.ExitError); ok && cliErr != nil { - return cliErr - } else if err != nil { - return common.NewExitError(err, codes.ErrorGeneric) + if err != nil { + return err } return nil }, diff --git a/cmd/sops/subcommand/publish/publish.go b/cmd/sops/subcommand/publish/publish.go index 6c22988ca..fa7dba8cf 100644 --- a/cmd/sops/subcommand/publish/publish.go +++ b/cmd/sops/subcommand/publish/publish.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io/ioutil" - "os" "path/filepath" "strings" @@ -35,7 +34,6 @@ type Opts struct { KeyServices []keyservice.KeyServiceClient InputStore sops.Store OmitExtensions bool - Recurse bool } // Run publish operation @@ -45,31 +43,6 @@ func Run(opts Opts) error { if err != nil { return err } - info, err := os.Stat(path) - if err != nil { - return err - } - if info.IsDir() && !opts.Recurse { - return fmt.Errorf("can't operate on a directory") - } else if info.IsDir() && opts.Recurse { - err = filepath.Walk(opts.InputPath, func(subPath string, info os.FileInfo, err error) error { - subAbsPath, _ := filepath.Abs(subPath) - if !info.IsDir() && subAbsPath != path { - subOpts := opts - subOpts.InputPath = subPath - return Run(subOpts) - } else { - return nil - } - }) - if err != nil { - return err - } - return nil - } - fileSuffix := filepath.Ext(path) - opts.InputStore = common.DefaultStoreForPathOrFormat(path, fileSuffix) - destinationPath := opts.InputPath conf, err := config.LoadDestinationRuleForFile(opts.ConfigPath, opts.InputPath, make(map[string]*string)) if err != nil { @@ -78,8 +51,9 @@ func Run(opts Opts) error { if conf.Destination == nil { return errors.New("no destination configured for this file") } + destinationPath := opts.InputPath if opts.OmitExtensions || conf.OmitExtensions { - destinationPath = strings.TrimSuffix(destinationPath, fileSuffix) + destinationPath = strings.TrimSuffix(destinationPath, filepath.Ext(path)) } // Check that this is a sops-encrypted file @@ -176,13 +150,7 @@ func Run(opts Opts) error { } } if response == "n" { - msg := fmt.Sprintf("Publication of %s canceled", path) - if opts.Recurse { - fmt.Println(msg) - return nil - } else { - return errors.New(msg) - } + return errors.New("Publish canceled") } }