Skip to content

Commit

Permalink
Merge pull request #131 from twpayne/vault
Browse files Browse the repository at this point in the history
Add vault support
  • Loading branch information
twpayne committed Jan 15, 2019
2 parents 91e6934 + 1fe3fe0 commit c1d0b3b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ variables allow you to change behaviour depending on operating system,
architecture, and hostname.

* Secure: `chezmoi` can retreive secrets from
[Bitwarden](https://bitwarden.com/), [LastPass](https://lastpass.com/), your
Keychain (on macOS), and [GNOME
[Bitwarden](https://bitwarden.com/), [LastPass](https://lastpass.com/),
[Vault](https://www.vaultproject.io/), your Keychain (on macOS), and [GNOME
Keyring](https://wiki.gnome.org/Projects/GnomeKeyring) (on Linux).

* Robust: `chezmoi` updates all files and symbolic links atomically (using
Expand Down Expand Up @@ -356,6 +356,24 @@ example, you can extract a private SSH key like this:
Keys in the `note` section written as `CamelCase Words` are converted to
`camelCaseWords`.

### Using Vault

`chezmoi` includes support for [Vault](https://www.vaultproject.io/) using the
[Vault CLI](https://www.vaultproject.io/docs/commands/) to expose data as a
template function.

The vault CLI needs to be correctly configured on your machine, e.g. the
`VAULT_ADDR` and `VAULT_TOKEN` environment variables must be set correctly.
Verify that this is the case by running:

$ vault kv get -format=json <key>

The stuctured data from `vault kv get -format=json` is available as the `vault`
template function. You can use the `.Field` syntax of the `text/template`
language to extract the data you want. For example:

{{ (vault "<key>").data.data.password }}

### Using keyring

`chezmoi` includes support for Keychain (on macOS), GNOME Keyring (on Linux),
Expand Down
1 change: 1 addition & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Config struct {
SourceVCSCommand string
Bitwarden bitwardenCommandConfig
LastPass LastPassCommandConfig
Vault vaultCommandConfig
Data map[string]interface{}
funcs template.FuncMap
add addCommandConfig
Expand Down
56 changes: 56 additions & 0 deletions cmd/vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cmd

import (
"encoding/json"
"fmt"
"os/exec"
"strings"

"github.com/spf13/cobra"
"github.com/twpayne/chezmoi/lib/chezmoi"
vfs "github.com/twpayne/go-vfs"
)

var vaultCommand = &cobra.Command{
Use: "vault",
Short: "Execute the Vault CLI",
RunE: makeRunE(config.runVaultCommand),
}

type vaultCommandConfig struct {
Vault string
}

var vaultCache = make(map[string]interface{})

func init() {
rootCommand.AddCommand(vaultCommand)

config.Vault.Vault = "vault"
config.addFunc("vault", config.vaultFunc)
}

func (c *Config) runVaultCommand(fs vfs.FS, args []string) error {
return c.exec(append([]string{c.Vault.Vault}, args...))
}

func (c *Config) vaultFunc(key string) interface{} {
if data, ok := vaultCache[key]; ok {
return data
}
name := c.Vault.Vault
args := []string{"kv", "get", "-format=json", key}
if c.Verbose {
fmt.Printf("%s %s\n", name, strings.Join(args, " "))
}
output, err := exec.Command(name, args...).CombinedOutput()
if err != nil {
chezmoi.ReturnTemplateFuncError(fmt.Errorf("vault: %s %s: %v\n%s", name, strings.Join(args, " "), err, output))
}
var data interface{}
if err := json.Unmarshal(output, &data); err != nil {
chezmoi.ReturnTemplateFuncError(fmt.Errorf("vault: %s %s: %v\n%s", name, strings.Join(args, " "), err, output))
}
vaultCache[key] = data
return data
}

0 comments on commit c1d0b3b

Please sign in to comment.