Created
July 15, 2015 20:48
-
-
Save asdqwex/78d60af9e34a888c0918 to your computer and use it in GitHub Desktop.
4jim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Author: Jim Rosser | |
# Email: jarosser06@gmail.com | |
# | |
# Cloning a data bag: | |
# This will create a new data bag with the same items as the existing | |
# data bag. If -n is not set it will create a new key and encrypt the | |
# new data bag with that. | |
# | |
# Create data bag new_data_bag that has been encrypted with a new key: | |
# data-bag-secrets -e my_secret_file clone existing_data_bag new_data_bag | |
# | |
# Clone existin_data_bag to new_data_bag encrypted with the same key: | |
# data-bag-secrets -e my_secret_file -n my_secret_file clone existing_data_bag new_data_bag | |
# | |
# Rotating a data bag: | |
# This will rotate one or more encrypted data bags with a new key. | |
# | |
# Rotate bag1, bag2, and bag3 with a pre-created secret file: | |
# data-bag-secrets -e old_secret_file -n new_secret_file rotate bag1,bag2,bag3 | |
# | |
# Rotate bag1 with a key generated by this command, the key used will be | |
# named secret.pem and located in the current working directory: | |
# data-bag-secrets -e old_secret_file rotate bag1 | |
# | |
existing_key="" | |
new_key="" | |
random_str=$(cat /dev/urandom | LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) | |
tmp_dir="/tmp/${random_str}" | |
COMMAND_NAME="data-bag-secrets" | |
function usage { | |
cat <<EOF | |
Some helpful commands to manipulate secret data bags. | |
Usage: | |
${COMMAND_NAME} [opts] command [command args] | |
Options: | |
-h - show this usage | |
-e - existing data bag secret file | |
-n - new secret file | |
Commands: | |
rotate - rotates a data bag with a new secret file | |
clone - clones a data bag to a new name | |
kitchen - clones a data bag or all data bags to local secrets | |
EOF | |
} | |
function cleanup { | |
rm -rf $tmp_dir | |
} | |
function key_gen { | |
openssl rand -base64 512 | LC_CTYPE=C tr -d '\r\n' > secret.pem | |
} | |
function new_key_warn { | |
if [ -z $new_key ]; then | |
echo "Warning: you did not pass a new key so one will be gereated for you!" | |
fi | |
} | |
function fail() { | |
message=$1 | |
echo "Error: ${message}" | |
exit 1 | |
} | |
function fail_with_usage() { | |
message=$1 | |
echo -e "\nError: ${message}\n" | |
usage | |
exit 1 | |
} | |
function download_data_bag() { | |
existing_data_bag=$1 | |
if [ -z $existing_data_bag ]; then | |
fail "download_data_bag() missing argument existing_data_bag" | |
fi | |
data_bag_items=$(knife data bag show ${existing_data_bag}) | |
if ! [ $? -eq 0 ]; then | |
fail "knife data bag show ${existing_data_bag} returned non zero value" | |
fi | |
dir=${tmp_dir}/${existing_data_bag} | |
mkdir -p $dir | |
for item in $data_bag_items | |
do | |
knife data bag show $existing_data_bag $item -F json --secret-file $existing_key > ${dir}/${item}.json | |
## Fail out if knife returns something other than 0 | |
if ! [ $? -eq 0 ]; then | |
fail "something went wrong with 'knife data bag show ${existing_data_bag} ${item} -F json --secret-file ${existing_key} > ${dir}/${item}.json'" | |
fi | |
done | |
} | |
function clone_data_bag() { | |
existing_data_bag=$1 | |
new_data_bag=$2 | |
if [ -z $existing_data_bag ]; then | |
fail "download_data_bag() missing argument existing_data_bag" | |
fi | |
if [ -z $new_data_bag ]; then | |
fail "clone_data_bag() missing argument new_data_bag" | |
fi | |
if [ -z $existing_key ]; then | |
fail "missing existing secret key" | |
fi | |
mkdir $tmp_dir | |
download_data_bag $1 | |
## Assume we are rotating the same data bag if both are the same | |
if ! [ $existing_data_bag == $new_data_bag ]; then | |
mv ${tmp_dir}/${existing_data_bag} ${tmp_dir}/${new_data_bag} | |
fi | |
key=$new_key | |
if [ -z $key ]; then | |
new_key_warn | |
key_gen | |
key=$(pwd)/secret.pem | |
fi | |
knife data bag create $new_data_bag | |
knife data bag from file $new_data_bag ${tmp_dir}/${new_data_bag} --secret-file $key | |
## Call cleanup function to make sure the secrets are cleaned up | |
## only if nothing went wrong | |
if [ $? -eq 0 ]; then | |
cleanup | |
else | |
fail "something went wrong with the upload, downloaded data is located in ${tmp_dir}" | |
fi | |
} | |
while getopts ":e:n:h" flag | |
do | |
case $flag in | |
h) | |
usage | |
exit 1 | |
;; | |
e) | |
existing_key=$OPTARG | |
;; | |
n) | |
new_key=$OPTARG | |
;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
case $1 in | |
rotate) | |
if [ "$2" == "-h" ]; then | |
echo "${COMMAND_NAME} -e <existing-key> [-n <new-key>] rotate <comma delimited data-bags>" | |
exit 1 | |
fi | |
## Fail out if no data bag is passed | |
if [ -z $2 ]; then | |
fail "must pass at least one data bag to rotate" | |
fi | |
for bag in $(echo ${2} | LC_CTYPE=C tr ',' ' ') | |
do | |
clone_data_bag $bag $bag | |
done | |
;; | |
clone) | |
if [ "$2" == "-h" ]; then | |
echo "${COMMAND_NAME} -e <existing-key> -n <new-key> clone <existing-data-bag-name> <new-data-bag-name>" | |
exit 1 | |
fi | |
knife data bag show $new_data_bag &> /dev/null | |
if [ $? -eq 0 ]; then | |
fail "data bag ${new_data_bag} already exists" | |
fi | |
clone_data_bag $2 $3 | |
;; | |
kitchen) | |
if [ "$2" == "-h" ]; then | |
echo "${COMMAND_NAME} -e <existing-key> kitchen" | |
exit 1 | |
fi | |
echo "Not yet implemented... Jim is lazy" | |
;; | |
*) | |
fail "unknown commmand ${1}" | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment