2023-01-11 06:57:58 +00:00
|
|
|
// Copyright © 2022 Roberto Hidalgo <joao@un.rob.mx>
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"git.rob.mx/nidito/chinampa/pkg/command"
|
|
|
|
"git.rob.mx/nidito/joao/pkg/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
var GitFilters = []*command.Command{
|
|
|
|
FilterDiff,
|
|
|
|
FilterClean,
|
|
|
|
FilterGroup,
|
|
|
|
}
|
|
|
|
|
|
|
|
func redactedData(cmd *command.Command) error {
|
|
|
|
path := cmd.Arguments[0].ToValue().(string)
|
|
|
|
|
|
|
|
flush := false
|
|
|
|
if opt, ok := cmd.Options["flush"]; ok {
|
|
|
|
flush = opt.ToValue().(bool)
|
|
|
|
}
|
|
|
|
|
|
|
|
contents, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg, err := config.FromYAML(contents)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if flush {
|
|
|
|
name, vault, err := config.VaultAndNameFrom(path, contents)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg.Name = name
|
|
|
|
cfg.Vault = vault
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := cfg.AsYAML(config.OutputModeRedacted)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = cmd.Cobra.OutOrStdout().Write(res)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var FilterGroup = &command.Command{
|
|
|
|
Path: []string{"git-filter"},
|
|
|
|
Summary: "Subcommands used by `git` as filters",
|
|
|
|
Description: `In order to store configuration files within a git repository while keeping secrets off remote copies, ﹅joao﹅ provides git filters.
|
|
|
|
|
|
|
|
To install them, **every collaborator** would need to run:
|
|
|
|
|
|
|
|
﹅﹅﹅sh
|
|
|
|
# setup filters in your local copy of the repo:
|
|
|
|
# this runs when you check in a file (i.e. about to commit a config file)
|
|
|
|
# it will flush secrets to 1password before removing secrets from the file on disk
|
|
|
|
git config filter.joao.clean "joao git-filter clean --flush %f"
|
|
|
|
# this step runs after checkout (i.e. pulling changes)
|
|
|
|
# it simply outputs the file as-is on disk
|
|
|
|
git config filter.joao.smudge cat
|
|
|
|
# let's enforce these filters
|
|
|
|
git config filter.joao.required true
|
|
|
|
|
2023-01-14 21:56:32 +00:00
|
|
|
# optionally, configure a diff filter to show changes as would be committed to git
|
2023-01-11 06:57:58 +00:00
|
|
|
# this does not modify the original file on disk
|
|
|
|
git config diff.joao.textconv "joao git-filter diff"
|
|
|
|
﹅﹅﹅
|
|
|
|
|
|
|
|
Then, **only once**, we need to specify which files to apply the filters and diff commands to:
|
|
|
|
|
|
|
|
﹅﹅﹅sh
|
|
|
|
# adds diff and filter attributes for config files ending with .joao.yaml
|
|
|
|
echo '**/*.joao.yaml filter=joao diff=joao' >> .gitattributes
|
|
|
|
# finally, commit and push these attributes
|
|
|
|
git add .gitattributes
|
|
|
|
git commit -m "installing joao attributes"
|
|
|
|
git push origin main
|
|
|
|
﹅﹅﹅
|
|
|
|
|
|
|
|
See:
|
|
|
|
- https://git-scm.com/docs/gitattributes#_filter
|
|
|
|
- https://git-scm.com/docs/gitattributes#_diff`,
|
|
|
|
Arguments: command.Arguments{},
|
|
|
|
Options: command.Options{},
|
|
|
|
Action: func(cmd *command.Command) error {
|
|
|
|
data, err := cmd.ShowHelp(command.Root.Options, os.Args)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err = cmd.Cobra.OutOrStderr().Write(data)
|
|
|
|
return err
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var FilterDiff = &command.Command{
|
|
|
|
Path: []string{"git-filter", "diff"},
|
|
|
|
Summary: "a filter for git to call during `git diff`",
|
|
|
|
Description: `see ﹅joao git-filter﹅ for instructions to install this filter`,
|
|
|
|
Arguments: command.Arguments{
|
|
|
|
{
|
|
|
|
Name: "path",
|
|
|
|
Description: "The git staged path to read from",
|
|
|
|
Required: true,
|
|
|
|
Values: &command.ValueSource{
|
2023-01-14 23:29:02 +00:00
|
|
|
Files: &fileExtensions,
|
2023-01-11 06:57:58 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Options: command.Options{},
|
|
|
|
Action: redactedData,
|
|
|
|
}
|
|
|
|
|
|
|
|
var FilterClean = &command.Command{
|
|
|
|
Path: []string{"git-filter", "clean"},
|
|
|
|
Summary: "a filter for git to call when a file is checked in",
|
|
|
|
Description: `see ﹅joao git-filter﹅ for instructions to install this filter
|
|
|
|
|
|
|
|
Use ﹅--flush﹅ to save changes to 1password before redacting file.`,
|
|
|
|
Arguments: command.Arguments{
|
|
|
|
{
|
|
|
|
Name: "path",
|
|
|
|
Description: "The git staged path to read from",
|
|
|
|
Required: true,
|
|
|
|
Values: &command.ValueSource{
|
2023-01-14 23:29:02 +00:00
|
|
|
Files: &fileExtensions,
|
2023-01-11 06:57:58 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Options: command.Options{
|
|
|
|
"flush": {
|
|
|
|
Description: "Save to 1Password after before redacting",
|
|
|
|
Type: "bool",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Action: redactedData,
|
|
|
|
}
|