getsops / sops

Simple and flexible tool for managing secrets
https://getsops.io/
Mozilla Public License 2.0
17.03k stars 879 forks source link

Editing file in-place with data from stdin #696

Open elsbrock opened 4 years ago

elsbrock commented 4 years ago

I would like to be able to edit an already encrypted file in-place using the data from stdin so that I can use it as part of a script to modify a file. I am using a .sops.yaml file with pattern matching and multiple KMSs.

One option I found is to do -d | -e /dev/stdin, but that has the drawback that I need to specify the KMS to be used explicitly, although that is already configured in .sops.yaml.

Another possibility I could imagine is that the KMS pattern is taken from --output should that be specified.

What I don't get is why -i seems to open the editor in any case – can't it simply read from stdin if connected to a pipe? Or am I maybe missing something?

autrilla commented 4 years ago

Can you explain exactly what kind of edit you want to make to the file? --set might work for you.

Another, more flexible way to do it is writing a custom editor.

-i has no bearing on whether the editor is open or not. Actually, -i should have no effect at all when using the editor mode.

elsbrock commented 4 years ago

I am basically trying to do the following:

sops -d myfile.dev.yaml | yq w - my.key $value | sops --in-place-edit myfile.dev.yaml

The reason I am not using the native YAML editing capabilities is because I'd have to construct the my.key value in my shell script to conform to sops expectation (["my"]["key”]). Besides, I would like to have a general way of editing a file in place, because the files I am working with might not necessarily be YAML or JSON.

keymon commented 1 year ago

I did a workaround to do something similar with json with jq.

I created a script able to edit the file "inplace":

#!/bin/bash

if [ "$#" -lt 2 ]; then
    cat <<EOF
Usage: $0 <args> <file>

Example:

    EDITOR="jq-inplace '...'" sops file.json
EOF
    exit 1
fi

file="${!#}"

# Remove the last argument from the positional parameters
set -- "${@:1:$(($#-1))}"

tmpfile="$(mktemp)"
trap 'rm -f $tmpfile' EXIT
cat "$file" | jq "$@" > "$tmpfile"
mv -f "$tmpfile" "$file"

And then I call it by setting $EDITOR

EDITOR="jq-inplace.sh 'to_entries | map(.value|=(to_entries|map(.key|=ascii_upcase)|from_entries))|from_entries'" sops secrets.tfvars.json