Last active
February 7, 2019 21:13
-
-
Save monking/7dff8920eb84bdcf2031d5c7eab23a5f to your computer and use it in GitHub Desktop.
AWS scripts: authenticate & edit on S3
This file contains hidden or 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 | |
# https://aws.amazon.com/premiumsupport/knowledge-center/authenticate-mfa-cli/ | |
storage=credentialsFile | |
while getopts et: flag; do | |
case $flag in | |
t) mfaToken="$OPTARG";; | |
e) storage=env;; | |
esac | |
done | |
[[ ! -f ~/.aws/credentials ]] && { | |
1>&2 echo "Please run 'aws configure' first, to establish your default key/secret." | |
return 2 | |
} | |
[[ -z $AWS_MFA_SERIAL_NUMBER ]] && read -p "MFA serial number: " && export AWS_MFA_SERIAL_NUMBER="$REPLY" | |
case $storage in | |
env) | |
unset AWS_ACCESS_KEY_ID | |
unset AWS_SECRET_ACCESS_KEY | |
unset AWS_SESSION_TOKEN | |
;; | |
credentialsFile) | |
if [[ $REPLY =~ ^[Yy]? ]]; then | |
if [[ ! -f ~/.aws/credentials.perm ]]; then | |
cp ~/.aws/credentials ~/.aws/credentials.perm | |
fi | |
else | |
1>&2 echo "Authentication has been cancelled." | |
return 3 | |
fi | |
;; | |
esac | |
[[ -z $mfaToken ]] && read -p "MFA token: " mfaToken | |
1>&2 echo "confirming token: $mfaToken" | |
response="$(aws sts get-session-token --serial-number "$AWS_MFA_SERIAL_NUMBER" --token-code "$mfaToken")" | |
echo "$response" | json &>/dev/null || { | |
1>&2 echo -e "Invalid response:\n$response" | |
return 1 | |
} | |
ACCESS_KEY_ID="$(echo "$response" | json Credentials.AccessKeyId)" | |
SECRET_ACCESS_KEY="$(echo "$response" | json Credentials.SecretAccessKey)" | |
SESSION_TOKEN="$(echo "$response" | json Credentials.SessionToken)" | |
case $storage in | |
env) | |
export AWS_ACCESS_KEY_ID="$ACCESS_KEY_ID" | |
export AWS_SECRET_ACCESS_KEY="$SECRET_ACCESS_KEY" | |
export AWS_SESSION_TOKEN="$SESSION_TOKEN" | |
;; | |
credentialsFile) | |
cat > ~/.aws/credentials <<EOF | |
$(cat ~/.aws/credentials.perm) | |
[mfa] | |
aws_access_key_id = $ACCESS_KEY_ID | |
aws_secret_access_key = $SECRET_ACCESS_KEY | |
aws_session_token = $SESSION_TOKEN | |
EOF | |
1>&2 echo "Credentials updated." | |
;; | |
esac |
This file contains hidden or 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 | |
defaultLocalDir=/tmp/edit-on-s3 | |
showHelp() { | |
1>&2 echo " | |
OPTIONS: | |
-u URL The S3 URL of a file. To enable the use of CloudFront URLs, set the S3_URL_BUCKET_MAP environment variable (see below). | |
-b BUCKET The S3 bucket name. | |
-k KEY The S3 file key. | |
-h Show this help. | |
-l DIR Directory in which to store copies of the files before/after editing. By default, $defaultLocalDir. | |
ENVIRONMENT: | |
S3_URL_BUCKET_MAP | |
Path to a file with urls with bucket names or hostnames, whitespace, and | |
alias URLs. The first matching row is used. | |
This would usually be CloudFront CNAMEs. In this case, grab the contents of | |
the columns \"Origin\" and \"CNAMEs\" from the CloudFront Distributions | |
table (https://console.aws.amazon.com/cloudfront/home). | |
Note: any path in the origin (anything following '/') will be prepended | |
onto the path from the given URL to result in the S3 file key. | |
" | |
} | |
localDir="$defaultLocalDir" | |
bucket= | |
key= | |
while getopts u:b:k:hl: flag; do | |
case $flag in | |
u) url="$OPTARG";; | |
b) bucket="$OPTARG";; | |
k) key="$OPTARG";; | |
h) showHelp; exit 0;; | |
l) localDir="$OPTARG";; | |
esac | |
done | |
if [[ -n $url ]]; then | |
urlParts=($(echo -n "$url" | perl -pe 's#https?://([^/]+)/([^/]+)(/(.*))?#\1 \2 \4#')) | |
hostname="${urlParts[0]}" | |
firstPathSegment="${urlParts[1]}" | |
restOfPath="${urlParts[2]}" | |
if [[ $url =~ .s3.amazonaws.com ]]; then | |
echo "Getting bucket/key from S3 URL:" | |
bucket="$firstPathSegment" | |
key="$restOfPath" | |
elif [[ -s "$S3_URL_BUCKET_MAP" ]]; then | |
echo "using S3_URL_BUCKET_MAP: $S3_URL_BUCKET_MAP" | |
while read matchedS3Url aliases; do | |
if [[ -n $matchedS3Url ]]; then | |
matchS3Parts=($(echo -n "$matchedS3Url" | perl -pe 's#^([^.]*).s3.amazonaws.com(/(.*))?#\1 \3#')) | |
bucket="${matchS3Parts[0]}" | |
originPath="${matchS3Parts[1]}" | |
[[ -n $originPath && ! $originPath =~ /$ ]] && originPath+="/" | |
key="${originPath}${firstPathSegment}" | |
[[ -n $restOfPath ]] && key+="/${restOfPath}" | |
break | |
fi | |
done <<< $(grep -E "(\\s|,)$hostname(\\s|,|\$)" "$S3_URL_BUCKET_MAP") | |
else | |
echo "URL is not S3. If you know which S3 bucket it belongs to, populate a file per S3_URL_BUCKET_MAP (see below)." | |
echo | |
showHelp | |
exit 2 | |
fi | |
fi | |
if [[ -z $bucket || -z $key ]]; then | |
echo "Couldn't determine bucket or key." | |
showHelp | |
exit 1 | |
else | |
echo "bucket: $bucket" | |
echo "key: $key" | |
fi | |
time="$(date '+%Y-%m-%d.%H-%M-%S%z')" | |
localBucketDir="$localDir/$bucket" | |
mkdir -p "$localBucketDir" | |
basifiedKey="${key//\//+}" | |
localPath="$localBucketDir/edit-on-s3.${time}.$basifiedKey" | |
editableLocalPath="$localBucketDir/edit-on-s3.${time}.edit.$basifiedKey" | |
[[ -z $EDITOR ]] && EDITOR=vim | |
s3URI="s3://${bucket}/${key}" | |
aws --profile=mfa s3 cp "${s3URI}" "${localPath}" && | |
cp "${localPath}" "${editableLocalPath}" && | |
$EDITOR "${editableLocalPath}" | |
[[ -s "${editableLocalPath}" ]] && | |
[[ -n "$(diff "${localPath}" "${editableLocalPath}")" ]] && | |
echo "(DEBUG)" aws --profile=mfa s3 cp "${editableLocalPath}" "${s3URI}" && | |
aws --profile=mfa s3 cp "${editableLocalPath}" "${s3URI}" && | |
echo "Success!" || | |
echo "Either there were no changes to the file, or something went wrong... (apologies for the vague error)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tested on Mac, with AWS CLI (1.16.90,
brew install awscli
), and Bash 3.2.57