Last active
May 24, 2023 03:25
-
-
Save dwallraff/ac725d24196e83024ee145cc2cfb7ab3 to your computer and use it in GitHub Desktop.
Bash funtions
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
#! /usr/bin/env bash | |
# Check for requirements | |
function check_command { | |
if [ ! "$(command -v "$1")" ]; | |
then | |
echo "command $1 was not found" | |
return 1 | |
fi | |
} | |
# Log into 1Password CLI | |
function op_login { | |
# Check if op is installed | |
if ! check_command op; then | |
echo "The op cli is not installed. Aborting..." | |
return 1 | |
fi | |
# Check if op is logged in already | |
if ! op list items > /dev/null 2>&1; then | |
echo "op is already logged in" | |
return 0 | |
fi | |
echo "Logging into op" | |
# Check if op is logged in | |
if ! op list users > /dev/null 2>&1; then | |
# if not, log in or die trying | |
if ! eval "$(op signin my.1password.com [email protected])"; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
fi | |
} | |
# Create a slug from a string | |
# https://gist.github.com/oneohthree/f528c7ae1e701ad990e6 | |
function slugify { | |
echo "$1" | iconv -t ascii//TRANSLIT | sed -E s/[^a-zA-Z0-9]+/-/g | sed -E s/^-+\|-+$//g | tr '[:upper:]' '[:lower:]' | |
} | |
# Create an encrypted tarball | |
function enc_tar { | |
# Get some names and stuff | |
BASE=$(basename "$1") | |
TARBALL=$(slugify "$BASE") | |
# Log in to op | |
if ! op_login; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
# Dump op tar password from op into fd:3 | |
# https://unix.stackexchange.com/questions/29111/safe-way-to-pass-password-for-1-programs-in-bash#answer-29186 | |
echo "Getting op encrypted tarball password. This can take a hot minute....." | |
if ! exec 3<<<"$(op get item encrypted_tar_password | jq -r '.details.fields[] | select(.name=="password") | .value')"; then | |
echo "Unable to dump op encrypted tarball password to fd:3. Aborting..." | |
return 1 | |
fi | |
# Use that password to encrypt the tarball | |
echo "Tar'ing up '$1'" | |
if ! tar hcz "$1" | gpg --batch --cipher-algo AES256 --passphrase-fd 3 --symmetric --output "$TARBALL".tar.gz.enc > /dev/null; then | |
echo "Creating an encrypted tarball failed. Aborting..." | |
return 1 | |
fi | |
} | |
# Decrypt an encrypted tarball | |
function dec_tar { | |
# Strip the extensions so we know dir to put this into | |
SHORT=$(basename "$1" .tar.gz.enc) | |
mkdir -p "$SHORT" | |
mv "$1" "$SHORT"/. || die | |
# Log in to op | |
if ! op_login; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
# Dump op tar password from op into fd:3 | |
# https://unix.stackexchange.com/questions/29111/safe-way-to-pass-password-for-1-programs-in-bash#answer-29186 | |
echo "Getting op encrypted tarball password. This can take a hot minute....." | |
if ! exec 3<<<"$(op get item encrypted_tar_password | jq -r '.details.fields[] | select(.name=="password") | .value')"; then | |
echo "Unable to dump op encrypted tarball password to fd:3. Aborting..." | |
return 1 | |
fi | |
# Use that password to decrypt the tarball | |
cd "$SHORT" || die | |
echo "Untar'ing '$1'" | |
if ! gpg --no-verbose --quiet --batch --cipher-algo AES256 --passphrase-fd 3 --decrypt "$1" | tar xz; then | |
echo "Decrypting an encrypted tarball failed. Aborting..." | |
return 1 | |
fi | |
cd .. || die | |
} | |
# Create an encrypted tarball and upload it to google drive | |
function gdrive_upload { | |
# Check if rclone is installed | |
if ! check_command rclone; then | |
echo "The rclone cli is not installed. Aborting..." | |
return 1 | |
fi | |
# Get some names and stuff | |
BASE=$(basename "$1") | |
SLUG=$(slugify "$BASE") | |
TODAY=$(date "+%Y%m%d") | |
TARBALL_NAME="$TODAY"_"$SLUG" | |
# Log in to op | |
if ! op_login; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
# Dump op tar password from op into fd:3 | |
# https://unix.stackexchange.com/questions/29111/safe-way-to-pass-password-for-1-programs-in-bash#answer-29186 | |
echo "Getting op encrypted tarball password. This can take a hot minute....." | |
if ! exec 3<<<"$(op get item encrypted_tar_password | jq -r '.details.fields[] | select(.name=="password") | .value')"; then | |
echo "Unable to dump op encrypted tarball password to fd:3. Aborting..." | |
return 1 | |
fi | |
# Use that password to encrypt the tarball | |
echo "Tar'ing up '$1'" | |
if ! tar hcz "$1" | gpg --batch --cipher-algo AES256 --passphrase-fd 3 --symmetric --output "$TARBALL_NAME".tar.gz.enc > /dev/null; then | |
echo "Creating an encrypted tarball failed. Aborting..." | |
return 1 | |
fi | |
# Copy to gdrive | |
echo "Copying to gdrive" | |
if ! rclone copy "$TARBALL_NAME".tar.gz.enc "gdrive:/archive/encrypted backups" > /dev/null 2>&1; then | |
echo "Copying to rclone failed" | |
fi | |
# Clean up | |
echo "Cleaning up" | |
if ! rm "$TARBALL_NAME".tar.gz.enc; then | |
echo "Clean up failed" | |
fi | |
} | |
# Upload file to 1Password | |
function add_to_op { | |
# Check that we got a file, not a dir | |
if [[ ! -f "$1" ]]; then | |
echo "This only works with files. Please hang up and dial your extension again." | |
return 1 | |
fi | |
# Then set some vars | |
BASE=$(basename "$1") | |
SLUG=$(slugify "$BASE") | |
OLD_DOC="" | |
# Now that we're good, log into op | |
if ! op_login; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
# Find anything currently there | |
echo "Looking for older versions of $SLUG. This can take a hot minute....." | |
# shellcheck disable=2016 | |
OLD_DOC=$(op list documents | jq -r '. as $in | keys[] | select($in[.].overview.title | contains("'"$SLUG"'")) | select($in[.].trashed=="N") as $res | $in[$res].uuid') | |
# Let us know if it's a new doc | |
if [ -n "$OLD_DOC" ]; then | |
echo "Looks like we found an older version of $SLUG with an id of $OLD_DOC. We'll clean that up later." | |
fi | |
# Upload a new rclone to 1password | |
echo "Creating new $SLUG doc" | |
if ! op create document "$1" --title="$SLUG" --vault="Personal" --tags="uploaded_by_cli" > /dev/null; then | |
echo "Doc creation failed" | |
fi | |
# If there was an old doc, let's delete it | |
if [ -n "$OLD_DOC" ]; then | |
echo "Deleting the old one" | |
op delete item "$OLD_DOC" > /dev/null | |
fi | |
} | |
# Get info about my ip address | |
function ipinfo { | |
if [ $# -eq 0 ]; then | |
curl -s ip-api.com | |
else | |
curl -s ip-api.com/"$1" | |
fi | |
} | |
# Get the weather | |
function weather { | |
if [ $# -eq 0 ]; then | |
LOC="$(curl -s ip-api.com/json | jq -r .country)" | |
clear | |
curl -s http://wttr.in/"$LOC"?FQ2 | |
else | |
clear | |
curl -s http://wttr.in/"$1"?FQ2 | |
fi | |
} | |
# Find out git branch for prompt | |
function github_sso_token { | |
op_login | |
TEMP=$(op get item github_sso_token | jq -r '.details.fields[] | select(.name=="password") | .value') | |
echo '#!/usr/bin/env bash' > ~/.github_sso_token | |
echo "echo $TEMP" >> ~/.github_sso_token | |
chmod +x ~/.github_sso_token | |
export GIT_ASKPASS=~/.github_sso_token | |
} | |
# Add yubikey ssh functionality | |
function yubikey { | |
GPG_TTY=$(tty) | |
export GPG_TTY | |
gpg-connect-agent updatestartuptty /bye | |
unset SSH_AGENT_PID | |
SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) | |
export SSH_AUTH_SOCK | |
} | |
# 1password full export and backup | |
function 1password_backup { | |
### async op get item | |
### maxing out op api on even a split of 5, so not using for now | |
# split -l 5 "$BACKUPDIR"/items_list "$BACKUPDIR"/items_list_split | |
# # Loop over list and save off all the metadata | |
# COUNTER=0 | |
# TOTAL=$(wc -l < "$BACKUPDIR"/items_list) | |
# for cur_file in "$BACKUPDIR"/items_list_split*; do | |
# while read -r item; do | |
# (( COUNTER++ )) | |
# echo "Getting item #$COUNTER of $TOTAL..." | |
# op get item "$item" >> "$BACKUPDIR"/"$BACKUPDIR".json & | |
# done < "$cur_file"; | |
# wait | |
# done | |
# set some vars | |
TODAY=$(date "+%Y%m%d") | |
BACKUPDIR="$TODAY"_1password_backup | |
# Check if op is installed | |
if ! check_command op; then | |
echo "The op cli is not installed. Aborting..." | |
exit 1 | |
fi | |
# Check if op is logged in | |
if ! op_login; then | |
echo "op login failed. Aborting..." | |
return 1 | |
fi | |
# make a local temp dir | |
mkdir -p ~/"$BACKUPDIR"/files || exit 1 | |
# get all item's UUIDs | |
echo "Getting item list..." | |
if ! op list items | jq -r '.[].uuid' > "$BACKUPDIR"/items_list; then | |
echo "Failed to list items. Aborting..." | |
exit 1 | |
fi | |
# Loop over list and save off all the metadata | |
COUNTER=0 | |
TOTAL=$(wc -l < "$BACKUPDIR"/items_list) | |
while read -r i; do | |
(( COUNTER++ )) | |
echo "Getting item #$COUNTER of $TOTAL..." | |
op get item "$i" >> "$BACKUPDIR"/"$BACKUPDIR".json; echo >> "$BACKUPDIR"/"$BACKUPDIR".json | |
done < "$BACKUPDIR"/items_list | |
# Get all current (non-trashed) doc UUIDs and titles | |
# shellcheck disable=2016 | |
echo "Getting doc list..." | |
if ! op list documents | jq -r '. as $in | keys[] | select($in[.].trashed=="N") as $res | [$in[$res].uuid, $in[$res].overview.title] | @json' > "$BACKUPDIR"/files/docs_list; then | |
echo "Failed to list docs. Aborting..." | |
exit 1 | |
fi | |
# Loop over list and save each one off | |
TOTAL="$(wc -l < "$BACKUPDIR"/files/docs_list)" | |
for ((i=1; i<="$TOTAL"; i++)) | |
do | |
FILENAME="" | |
UUID="" | |
(( COUNT=i-1 )) | |
UUID=$(jq -rs '.['"$COUNT"'][0]' < "$BACKUPDIR"/files/docs_list) | |
FILENAME=$(op get item "$UUID" | jq -r '.details.documentAttributes.fileName') | |
if [ -z "$FILENAME" ]; then | |
FILENAME=$(jq -rs '.['"$COUNT"'][1]' < "$BACKUPDIR"/files/docs_list) | |
fi | |
echo "Getting doc $i of $TOTAL: $FILENAME ($UUID)..." | |
op get document "$UUID" > "$BACKUPDIR"/files/"$FILENAME" | |
done | |
# Dump openssl tar password from op into fd:3 | |
# https://unix.stackexchange.com/questions/29111/safe-way-to-pass-password-for-1-programs-in-bash#answer-29186 | |
echo "Getting op encrypted tarball password. This can take a hot minute....." | |
if ! xec 3<<<"$(op get item encrypted_tar_password | jq -r '.details.fields[] | select(.name=="password") | .value')"; then | |
echo "Unable to dump op encrypted tarball password to fd:3. Aborting..." | |
exit 1 | |
fi | |
# Use that password to encrypt rclone with a date | |
echo "Tar'ing up $BACKUPDIR" | |
if ! tar hcz "$BACKUPDIR" | gpg --batch --cipher-algo AES256 --passphrase-fd 3 --symmetric --output "$BACKUPDIR".tar.gz.enc > /dev/null; then | |
echo "Creating an encrypted tarball failed. Aborting..." | |
exit 1 | |
fi | |
# Copy to gdrive | |
echo "Copying to gdrive" | |
if ! rclone copy "$BACKUPDIR".tar.gz.enc "gdrive:/archive/encrypted backups/1password" > /dev/null 2>&1; then | |
echo "Copying to rclone failed" | |
fi | |
# Clean up | |
cd ~ || exit | |
echo "Cleaning up" | |
rm -r "$BACKUPDIR" "$BACKUPDIR".tar.gz.enc; | |
if [ $? -ne 0 ]; then | |
echo "Clean up failed" | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment