diff --git a/.milpa/commands/joao/release/build.sh b/.milpa/commands/joao/release/build.sh index 38a8505..ceffa4a 100644 --- a/.milpa/commands/joao/release/build.sh +++ b/.milpa/commands/joao/release/build.sh @@ -33,11 +33,12 @@ for platform in "${platforms[@]}"; do @milpa.log success "archived $package" done -echo -n "$MILPA_ARG_VERSION" > "$root/dist/latest-version" +echo -n "$MILPA_ARG_VERSION" > "$root/latest-version" @milpa.log info "uploading to cdn" +rclone copy --s3-acl=public-read "$root/latest-version" "cdn:cdn.rob.mx/tools/joao" rclone sync --s3-acl=public-read \ "$root/dist/" \ "cdn:cdn.rob.mx/tools/joao/$MILPA_ARG_VERSION/" || @milpa.fail "could not upload to CDN" @milpa.log complete "release for $MILPA_ARG_VERSION available at CDN" -rm -rf dist +rm -rf "$root/dist" "$root/latest-version" diff --git a/README.md b/README.md index 8aa2658..54b39cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # `joao` -A very wip configuration manager. Keeps config entries encoded as YAML in the filesystem, backs it up to 1Password, and syncs scrubbed copies to git. robots consume entries via 1Password Connect + Vault. +A very WIP configuration manager. Keeps config entries encoded as YAML in the filesystem, backs it up to 1Password, and syncs scrubbed copies to git. robots consume entries via 1Password Connect + Vault. ## Usage @@ -48,7 +48,7 @@ And thus, I set to write me, yet again, some configuration toolchain that: - Allows the _structure_ of config trees to live happily **in the filesystem**: my home+cloud DC uses a lot of configuration spread over multiple files, one-off services don't really need the whole folder structure—I want a single tool to handle both. - Prevents _secrets_ from ending up in **remote repositories**: I really dig `git-crypt`'s filters, not quite sure about how to safely operate them yet... - Makes it **easy to edit** entries locally, as well as on the go: Easy for me to R/W, so YAML files, and 1Password's tools are pretty great for quick edits remotely. -- Is capable of bootstrapping other secret mangement processes: A single binary can talk to `op`'s CLI (hello, touch ID on macos!), to a 1password-connect server, and to vault as a plugin. +- Is capable of bootstrapping other secret management processes: A single binary can talk to `op`'s CLI (hello, touchID on MacOS!), to a 1password-connect server, and to vault as a plugin. For a deeper dive on these points above, check out my [docs/letter-to-secret-santa.md](docs/letter-to-secret-santa.md). @@ -65,7 +65,7 @@ The ideal workflow is: 1. configs are written to disk, temporarily 2. `joao flush --redact`es them to 1password, and removes secrets from disk 3. configuration values, secret or not, are read from: - - `joao get` as needed by local processes. Mostly thinking of the human in the loop here, where `op` and suitable auth (i.e. touchid) workflows are available. + - `joao get` as needed by local processes. Mostly thinking of the human in the loop here, where `op` and suitable auth (i.e. touchID) workflows are available. - from 1Password Connect, for when vault is not configured or available (think during provisioning) - from Hashicorp Vault, for any automated process, after provisioning is complete. @@ -78,7 +78,7 @@ The ideal workflow is: ### Repo mode -Basically, configs are kept in a directory and their relative path maps to their 1Password item name. A `.joao.yaml` file must exist at the root configuration directory, specifying the 1Password vault to use, and optionally a prefix to prepend ot every item name +Basically, configs are kept in a directory and their relative path maps to their 1Password item name. A `.joao.yaml` file must exist at the root configuration directory, specifying the 1Password vault to use, and optionally a prefix to prepend to every item name ```yaml # config/.joao.yaml diff --git a/internal/op-client/cli.go b/internal/op-client/cli.go index 46ae25a..d99a526 100644 --- a/internal/op-client/cli.go +++ b/internal/op-client/cli.go @@ -31,6 +31,10 @@ func DefaultExec(program string, args []string, stdin *bytes.Buffer) (stdout byt cmd.Stdout = &stdout var stderr bytes.Buffer cmd.Stderr = &stderr + if stdin != nil { + cmd.Stdin = stdin + } + if err = cmd.Run(); err != nil { return stderr, fmt.Errorf("op exited with %s:\n%s", err, stderr.Bytes()) } @@ -53,11 +57,12 @@ func invoke(dryRun bool, vault string, stdin *bytes.Buffer, args ...string) (byt argString := strings.Join(args, " ") if dryRun { logrus.Warnf("dry-run: Would have invoked `op %s`", argString) - logrus.Warnf("dry-run: stdin `%s`", stdin) + logrus.Tracef("dry-run: stdin `%s`", stdin) return bytes.Buffer{}, nil } logrus.Debugf("running `%s %s`", Path, argString) + logrus.Tracef("stdin `%s`", stdin) return Exec(Path, args, stdin) } @@ -114,6 +119,8 @@ func (b *CLI) Update(item *op.Item, remote *op.Item) error { } func (b *CLI) UpdateModern(updated *op.Item, original *op.Item) error { + updated.ID = original.ID + updated.Vault = original.Vault itemJSON, err := json.Marshal(updated) if err != nil { return fmt.Errorf("could not serialize op item into json: %w", err)