add redact command

uniformize extension completion
abstract config.AsFile(path)
This commit is contained in:
Roberto Hidalgo 2023-01-14 17:29:02 -06:00
parent 6589a35aa7
commit c94f1cda76
14 changed files with 106 additions and 38 deletions

View File

@ -1,4 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright © 2022 Roberto Hidalgo <joao@un.rob.mx>
# SPDX-License-Identifier: Apache-2.0
platforms=( platforms=(
linux/amd64 linux/amd64

View File

@ -19,7 +19,7 @@ var Diff = &command.Command{
Required: false, Required: false,
Variadic: true, Variadic: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"joao.yaml"}, Files: &fileExtensions,
}, },
}, },
}, },

View File

@ -3,10 +3,6 @@
package cmd package cmd
import ( import (
"fmt"
"io/fs"
"os"
"git.rob.mx/nidito/chinampa/pkg/command" "git.rob.mx/nidito/chinampa/pkg/command"
"git.rob.mx/nidito/joao/pkg/config" "git.rob.mx/nidito/joao/pkg/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -23,7 +19,7 @@ var Fetch = &command.Command{
Required: false, Required: false,
Variadic: true, Variadic: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"joao.yaml"}, Files: &fileExtensions,
}, },
}, },
}, },
@ -49,22 +45,16 @@ var Fetch = &command.Command{
return err return err
} }
if dryRun := cmd.Options["dry-run"].ToValue().(bool); dryRun {
b, err := local.AsYAML() b, err := local.AsYAML()
if err != nil { if err != nil {
return err return err
} }
if dryRun := cmd.Options["dry-run"].ToValue().(bool); dryRun {
logrus.Warnf("dry-run: would write to %s", path) logrus.Warnf("dry-run: would write to %s", path)
_, _ = cmd.Cobra.OutOrStdout().Write(b) _, _ = cmd.Cobra.OutOrStdout().Write(b)
} else { } else {
var mode fs.FileMode = 0644 if err := local.AsFile(path); err != nil {
if info, err := os.Stat(path); err == nil { return err
mode = info.Mode().Perm()
}
if err := os.WriteFile(path, b, mode); err != nil {
return fmt.Errorf("could not save changes to %s: %w", path, err)
} }
} }

View File

@ -22,7 +22,7 @@ var Flush = &command.Command{
Required: false, Required: false,
Variadic: true, Variadic: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"yaml"}, Files: &fileExtensions,
}, },
}, },
}, },
@ -31,6 +31,10 @@ var Flush = &command.Command{
Description: "Don't persist to 1Password", Description: "Don't persist to 1Password",
Type: "bool", Type: "bool",
}, },
"redact": {
Description: "Redact local file after flushing",
Type: "bool",
},
}, },
Action: func(cmd *command.Command) error { Action: func(cmd *command.Command) error {
paths := cmd.Arguments[0].ToValue().([]string) paths := cmd.Arguments[0].ToValue().([]string)
@ -48,6 +52,12 @@ var Flush = &command.Command{
if err := opclient.Update(cfg.Vault, cfg.Name, cfg.ToOP()); err != nil { if err := opclient.Update(cfg.Vault, cfg.Name, cfg.ToOP()); err != nil {
return fmt.Errorf("could not flush to 1password: %w", err) return fmt.Errorf("could not flush to 1password: %w", err)
} }
if cmd.Options["redact"].ToValue().(bool) {
if err := cfg.AsFile(path); err != nil {
return err
}
}
} }
logrus.Info("Done") logrus.Info("Done")

View File

@ -31,7 +31,7 @@ looks at the filesystem or remotely, using 1password (over the CLI if available,
Description: "The configuration to get from", Description: "The configuration to get from",
Required: true, Required: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"yaml", "yml"}, Files: &fileExtensions,
}, },
}, },
{ {

View File

@ -111,7 +111,7 @@ var FilterDiff = &command.Command{
Description: "The git staged path to read from", Description: "The git staged path to read from",
Required: true, Required: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"yaml", "yml"}, Files: &fileExtensions,
}, },
}, },
}, },
@ -131,7 +131,7 @@ Use ﹅--flush﹅ to save changes to 1password before redacting file.`,
Description: "The git staged path to read from", Description: "The git staged path to read from",
Required: true, Required: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"yaml", "yml"}, Files: &fileExtensions,
}, },
}, },
}, },

43
cmd/redact.go Normal file
View File

@ -0,0 +1,43 @@
// Copyright © 2022 Roberto Hidalgo <joao@un.rob.mx>
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"git.rob.mx/nidito/chinampa/pkg/command"
"git.rob.mx/nidito/joao/pkg/config"
"github.com/sirupsen/logrus"
)
var Redact = &command.Command{
Path: []string{"redact"},
Summary: "removes secrets from configuration",
Description: `Removes secret values (not the keys) from existing items for every ﹅CONFIG﹅ file provided.`,
Arguments: command.Arguments{
{
Name: "config",
Description: "The configuration file(s) to redact",
Required: false,
Variadic: true,
Values: &command.ValueSource{
Files: &fileExtensions,
},
},
},
Action: func(cmd *command.Command) error {
paths := cmd.Arguments[0].ToValue().([]string)
for _, path := range paths {
cfg, err := config.Load(path, false)
if err != nil {
return err
}
if err := cfg.AsFile(path); err != nil {
return err
}
}
logrus.Info("Done")
return nil
},
}

View File

@ -4,7 +4,6 @@ package cmd
import ( import (
"fmt" "fmt"
"io/fs"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
@ -29,7 +28,7 @@ Will read values from stdin (or ﹅--from﹅ a file) and store it at the ﹅PATH
Description: "The configuration file to modify", Description: "The configuration file to modify",
Required: true, Required: true,
Values: &command.ValueSource{ Values: &command.ValueSource{
Files: &[]string{"yaml"}, Files: &fileExtensions,
}, },
}, },
{ {
@ -119,20 +118,10 @@ Will read values from stdin (or ﹅--from﹅ a file) and store it at the ﹅PATH
} }
} }
b, err := cfg.AsYAML() if err := cfg.AsFile(path); err != nil {
if err != nil {
return err return err
} }
var mode fs.FileMode = 0644
if info, err := os.Stat(path); err == nil {
mode = info.Mode().Perm()
}
if err := os.WriteFile(path, b, mode); err != nil {
return fmt.Errorf("could not save changes to %s: %w", path, err)
}
if flush { if flush {
if err := opclient.Update(cfg.Vault, cfg.Name, cfg.ToOP()); err != nil { if err := opclient.Update(cfg.Vault, cfg.Name, cfg.ToOP()); err != nil {
return fmt.Errorf("could not flush to 1password: %w", err) return fmt.Errorf("could not flush to 1password: %w", err)

5
cmd/util.go Normal file
View File

@ -0,0 +1,5 @@
// Copyright © 2022 Roberto Hidalgo <joao@un.rob.mx>
// SPDX-License-Identifier: Apache-2.0
package cmd
var fileExtensions = []string{"joao.yaml", "yaml", "yml"}

View File

@ -9,6 +9,7 @@ import (
"git.rob.mx/nidito/joao/internal/vault" "git.rob.mx/nidito/joao/internal/vault"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin" "github.com/hashicorp/vault/sdk/plugin"
"github.com/sirupsen/logrus"
) )
var Plugin = &command.Command{ var Plugin = &command.Command{
@ -71,7 +72,10 @@ See:
Action: func(cmd *command.Command) error { Action: func(cmd *command.Command) error {
apiClientMeta := &api.PluginAPIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[2:]) err := flags.Parse(os.Args[2:])
if err != nil {
logrus.Warnf("Could not parse flags: %s", err)
}
tlsConfig := apiClientMeta.GetTLSConfig() tlsConfig := apiClientMeta.GetTLSConfig()
tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig) tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig)

4
go.mod
View File

@ -5,7 +5,7 @@ go 1.18
// replace git.rob.mx/nidito/chinampa => /Users/roberto/src/chinampa // replace git.rob.mx/nidito/chinampa => /Users/roberto/src/chinampa
require ( require (
git.rob.mx/nidito/chinampa v0.0.0-20230111054043-db21a53b2d20 git.rob.mx/nidito/chinampa v0.0.0-20230114231059-a14ffd07b963
github.com/1Password/connect-sdk-go v1.5.0 github.com/1Password/connect-sdk-go v1.5.0
github.com/alessio/shellescape v1.4.1 github.com/alessio/shellescape v1.4.1
github.com/hashicorp/go-hclog v1.4.0 github.com/hashicorp/go-hclog v1.4.0
@ -26,7 +26,7 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/charmbracelet/glamour v0.6.0 // indirect github.com/charmbracelet/glamour v0.6.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect github.com/dlclark/regexp2 v1.8.0 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fatih/color v1.13.0 // indirect github.com/fatih/color v1.13.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect

4
go.sum
View File

@ -1,6 +1,8 @@
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
git.rob.mx/nidito/chinampa v0.0.0-20230111054043-db21a53b2d20 h1:hHzbCNAFx9wdi3NyliugN6dTEX8dGsuup6wk2+8TmnI= git.rob.mx/nidito/chinampa v0.0.0-20230111054043-db21a53b2d20 h1:hHzbCNAFx9wdi3NyliugN6dTEX8dGsuup6wk2+8TmnI=
git.rob.mx/nidito/chinampa v0.0.0-20230111054043-db21a53b2d20/go.mod h1:obhWsLkUIlKJyhfa7uunrSs2O44JBqsegSAtAvY2LRM= git.rob.mx/nidito/chinampa v0.0.0-20230111054043-db21a53b2d20/go.mod h1:obhWsLkUIlKJyhfa7uunrSs2O44JBqsegSAtAvY2LRM=
git.rob.mx/nidito/chinampa v0.0.0-20230114231059-a14ffd07b963 h1:PRpd8b8qRkrQB8kSlF2jD1NxRC0Vau78qg1zMC3EJgs=
git.rob.mx/nidito/chinampa v0.0.0-20230114231059-a14ffd07b963/go.mod h1:obhWsLkUIlKJyhfa7uunrSs2O44JBqsegSAtAvY2LRM=
github.com/1Password/connect-sdk-go v1.5.0 h1:F0WJcLSzGg3iXEDY49/ULdszYKsQLGTzn+2cyYXqiyk= github.com/1Password/connect-sdk-go v1.5.0 h1:F0WJcLSzGg3iXEDY49/ULdszYKsQLGTzn+2cyYXqiyk=
github.com/1Password/connect-sdk-go v1.5.0/go.mod h1:TdynFeyvaRoackENbJ8RfJokH+WAowAu1MLmUbdMq6s= github.com/1Password/connect-sdk-go v1.5.0/go.mod h1:TdynFeyvaRoackENbJ8RfJokH+WAowAu1MLmUbdMq6s=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -45,6 +47,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.8.0 h1:rJD5HeGIT/2b5CDk63FVCwZA3qgYElfg+oQK7uH5pfE=
github.com/dlclark/regexp2 v1.8.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=

View File

@ -30,6 +30,7 @@ func main() {
cmd.Diff, cmd.Diff,
cmd.Fetch, cmd.Fetch,
cmd.Flush, cmd.Flush,
cmd.Redact,
cmd.Plugin, cmd.Plugin,
) )
chinampa.Register(cmd.GitFilters...) chinampa.Register(cmd.GitFilters...)

View File

@ -6,6 +6,8 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/fs"
"os"
op "github.com/1Password/connect-sdk-go/onepassword" op "github.com/1Password/connect-sdk-go/onepassword"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -140,3 +142,21 @@ func (cfg *Config) AsJSON(redacted bool, item bool) ([]byte, error) {
} }
return bytes, nil return bytes, nil
} }
func (cfg *Config) AsFile(path string) error {
b, err := cfg.AsYAML()
if err != nil {
return err
}
var mode fs.FileMode = 0644
if info, err := os.Stat(path); err == nil {
mode = info.Mode().Perm()
}
if err := os.WriteFile(path, b, mode); err != nil {
return fmt.Errorf("could not save config to file %s: %w", path, err)
}
return nil
}