2017-06-19 11:51:20 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/api"
|
|
|
|
homedir "github.com/mitchellh/go-homedir"
|
2024-04-10 16:44:42 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2022-07-02 16:31:11 +00:00
|
|
|
|
|
|
|
"github.com/Luzifer/go_helpers/v2/env"
|
|
|
|
"github.com/Luzifer/rconfig/v2"
|
2017-06-19 11:51:20 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
cfg struct {
|
|
|
|
LogLevel string `flag:"log-level" default:"info" description:"Verbosity of logs to use (debug, info, warning, error, ...)"`
|
|
|
|
VaultAddress string `flag:"vault-addr" env:"VAULT_ADDR" default:"https://127.0.0.1:8200" description:"Vault API address"`
|
|
|
|
VaultToken string `flag:"vault-token" env:"VAULT_TOKEN" vardefault:"vault-token" description:"Specify a token to use instead of app-id auth"`
|
|
|
|
VersionAndExit bool `flag:"version" default:"false" description:"Print program version and exit"`
|
|
|
|
}
|
|
|
|
|
|
|
|
version = "dev"
|
|
|
|
)
|
|
|
|
|
|
|
|
func vaultTokenFromDisk() string {
|
|
|
|
vf, err := homedir.Expand("~/.vault-token")
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
data, err := os.ReadFile(vf) //#nosec G304 // Intended to load file from disk
|
2017-06-19 11:51:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(data)
|
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
func initApp() (err error) {
|
|
|
|
rconfig.SetVariableDefaults(map[string]string{"vault-token": vaultTokenFromDisk()})
|
|
|
|
rconfig.AutoEnv(true)
|
2017-06-19 11:51:20 +00:00
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
if err = rconfig.Parse(&cfg); err != nil {
|
|
|
|
return fmt.Errorf("parsing CLI options: %w", err)
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
logLevel, err := logrus.ParseLevel(cfg.LogLevel)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("parsing log level: %w", err)
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
logrus.SetLevel(logLevel)
|
|
|
|
|
2017-06-19 11:51:20 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2024-04-10 16:44:42 +00:00
|
|
|
var err error
|
|
|
|
|
|
|
|
if err = initApp(); err != nil {
|
|
|
|
logrus.WithError(err).Fatal("initializing app")
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.VersionAndExit {
|
|
|
|
fmt.Printf("vault-patch %s\n", version) //nolint:forbidigo
|
|
|
|
os.Exit(0)
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
if len(rconfig.Args()) < 2 { //nolint:gomnd
|
|
|
|
logrus.Fatal("Usage: vault-patch [options] <path> <data>")
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
client, err := api.NewClient(&api.Config{
|
|
|
|
Address: cfg.VaultAddress,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2024-04-10 16:44:42 +00:00
|
|
|
logrus.WithError(err).Fatal("creating Vault client")
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
client.SetToken(cfg.VaultToken)
|
|
|
|
|
|
|
|
key := rconfig.Args()[1]
|
|
|
|
|
|
|
|
s, err := client.Logical().Read(key)
|
|
|
|
if err != nil || s == nil {
|
2024-04-10 16:44:42 +00:00
|
|
|
logrus.WithError(err).Fatal("reading key from vault")
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data := s.Data
|
|
|
|
if data == nil {
|
2024-04-10 16:44:42 +00:00
|
|
|
data = make(map[string]any)
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
for k, v := range env.ListToMap(rconfig.Args()[2:]) {
|
2017-06-19 11:51:20 +00:00
|
|
|
data[k] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := client.Logical().Write(key, data); err != nil {
|
2024-04-10 16:44:42 +00:00
|
|
|
logrus.WithError(err).Fatal("writing data to key")
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 16:44:42 +00:00
|
|
|
logrus.Print("data successfully written to key")
|
2017-06-19 11:51:20 +00:00
|
|
|
}
|