J'essaie de configurer le filtre Clean / Smudge dans git pour avoir le cryptage et le décryptage automatiques des fichiers contenant des secrets via la commande ansible-vault .
La particularité de la commande ansible-vault est qu'elle n'est pas idempotente (elle crée un binaire différent à chaque fois qu'elle est invoquée sur les mêmes données).
J'ai commencé avec l'implémentation suggérée dans cette page de blog . Malheureusement, cela n'a pas fonctionné correctement, car chaque fois que smudge est appelé (que ce soit un git checkout ou simplement git status), les fichiers secrets ont l'air modifiés pour git, même s'il ne l'est pas.
Je me suis donc demandé si git comparerait le binaire qu'il a dans l'index avec le fichier actuel filtré et j'ai essayé de construire sur ce script comme suit:
#!/bin/sh -x
# clean filter, it is invoked with %f
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
# get the plain text from the binary in the index
tmphead=`mktemp`
git show HEAD:$1 > $tmphead
contenthead=`echo "embedded" | ansible-vault view $tmphead --vault-password-file=$HOME/.vault_password`
export PAGER=cat
echo -n "$contenthead" | tee $tmphead
# if current and index plain text version differ
if [ "`md5sum $tmp | cut -d' ' -f1`" != "`md5sum $tmphead | cut -d' ' -f1`" ]; then
tmpcrypt=`mktemp`
cp $tmp $tmpcrypt
# generate a new crypted blob
echo "embedded" | ansible-vault encrypt $tmpcrypt --vault-password-file=$HOME/.vault_password > /dev/null 2>&1
cat "$tmpcrypt"
else
# just return the HEAD version
cat "$tmphead"
fi
rm $tmp $tmphead $tmpcrypt
La différence ici est qu'il essaie de comparer les versions actuelles et HEAD des fichiers secrets en texte brut (non cryptés), et seulement dans le cas où ils diffèrent, un nouveau blob binaire crypté avec ansible-vault.
Malheureusement, après ce changement, git continue de penser que le fichier secret est toujours modifié. Même après avoir à nouveau git add
généré le fichier, afin que le blob git soit calculé, git pense que le fichier est différent et laisse le changement entrer dans le commit. Notez que git diff
renvoyez les modifications vides, comme il se doit.
Pour référence, c'est une tache:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
export PAGER='cat'
CONTENT="`echo "embedded" | ansible-vault view "$tmp" --vault-password-file=$HOME/.vault_password 2> /dev/null`"
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
echo "Looks like one file was commited clear text"
echo "Please fix this before continuing !"
exit 1
else
echo -n "$CONTENT"
fi
rm $tmp
et c'est diff:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
export PAGER='cat'
CONTENT=`echo "embedded" | ansible-vault view "$1" --vault-password-file=$HOME/.vault_password 2> /dev/null`
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
cat "$1"
else
echo "$CONTENT"
fi
-n
de l'écho des taches, mais c'est une supposition. Pas d'option cachée pour git diff lui disant d'ignorer les fins de ligne unique?