Last active
April 25, 2023 05:45
-
-
Save MathiasKoch/19161eb3c8ce137bfcdbdafc614caf6e to your computer and use it in GitHub Desktop.
Migrate `Device` DynamoDB table in mgmt account to support new Duo v2
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
#!/usr/bin/env bash | |
declare -gA CRED_MAP=() | |
assume_role() { | |
CREDENTIALS=`aws sts assume-role --role-arn arn:aws:iam::$1:role/ExternalAccessProvisionIoT --role-session-name "VERSION-MIGRATION" --duration-seconds 3600 --output=json` | |
AWS_ACCESS_KEY_ID=`echo ${CREDENTIALS} | jq -r '.Credentials.AccessKeyId'` | |
AWS_SECRET_ACCESS_KEY=`echo ${CREDENTIALS} | jq -r '.Credentials.SecretAccessKey'` | |
AWS_SESSION_TOKEN=`echo ${CREDENTIALS} | jq -r '.Credentials.SessionToken'` | |
AWS_EXPIRATION=`echo ${CREDENTIALS} | jq -r '.Credentials.Expiration'` | |
echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN AWS_EXPIRATION=$AWS_EXPIRATION" | |
} | |
DRY_RUN=0 | |
DEVICES=`aws dynamodb scan --table-name Devices --no-paginate --filter-expression 'attribute_not_exists(hardwareMinor) AND deviceType = :devType' --expression-attribute-values '{":devType":{"S":"FbDuo"}}' | jq '.Items'` | |
TOTAL=`echo $DEVICES | jq 'length'` | |
I=0 | |
for UUID in $(echo $DEVICES | jq '.[] | .uuid.S' | xargs); do | |
((I=I+1)) | |
echo -n "[$I/$TOTAL] Running migration for $UUID.. " | |
VERSION=`echo $DEVICES | jq -r --arg uuid $UUID '.[] | select(.uuid.S == $uuid) | .hardwareVersion.S'` | |
MINOR=`echo $DEVICES | jq -r --arg uuid $UUID '.[] | select(.uuid.S == $uuid) | .hardwareMinor.S // empty'` | |
CLAIMED_BY_ACC=`echo $DEVICES | jq -r --arg uuid $UUID '.[] | select(.uuid.S == $uuid) | .claimedBy.M.awsAcc.S // empty'` | |
if [[ -z "$MINOR" ]]; then | |
IFS=._ read -r MAJOR MINOR <<< $VERSION | |
else | |
echo -e "\xE2\x98\x85" | |
continue | |
fi | |
# Validate MAJOR & MINOR | |
if [[ -z "$MAJOR" ]]; then | |
>&2 echo "MAJOR NOT SET?!" | |
echo -e "\xE2\x9D\x8C" | |
continue | |
fi | |
if [[ -z "$MINOR" ]]; then | |
>&2 echo "MINOR NOT SET" | |
fi | |
# Strip prefixed 'v' if it exists, as we add that to all instances upon insert | |
MAJOR=${MAJOR#"v"} | |
UPDATE_EXPR="SET hardwareVersion = :hardwareVersion, hardwareMinor = :hardwareMinor" | |
EXPR_ATTR_VALUES="{\":hardwareVersion\":{\"S\":\"v$MAJOR\"},\":hardwareMinor\":{\"S\":\"$MINOR\"}" | |
if [[ ! -z "$CLAIMED_BY_ACC" ]]; then | |
if [[ -v CRED_MAP["$CLAIMED_BY_ACC"] ]]; then | |
CREDS=`echo "${CRED_MAP[$CLAIMED_BY_ACC]}"` | |
else | |
CREDS=`assume_role $CLAIMED_BY_ACC` | |
CRED_MAP+=(["$CLAIMED_BY_ACC"]="$CREDS") | |
fi | |
STATUS=`export $CREDS; aws iot-data get-thing-shadow --thing-name $UUID --shadow-name status shadow 2>/dev/null && jq '.state.reported.firmware_versions' shadow && rm shadow` | |
if [ $? -ne 0 ]; then | |
# "No status shadow found. Checking S3 healthdump.." | |
OBJECTS=`export $CREDS; aws s3 ls s3://$CLAIMED_BY_ACC-eu-west-1-duo-healthdump/fbduo/status/$UUID/ 2>/dev/null` | |
if [ $? -eq 0 ]; then | |
if [ "$(echo $OBJECTS | wc -l)" == "1000" ]; then | |
echo "MORE THAN ONE PAGE FOUND?!" | |
fi | |
LATEST=`echo $OBJECTS | tail -n 1 | awk '{print $4}'` | |
FIRMWARE=`export $CREDS; aws s3 cp --quiet s3://$CLAIMED_BY_ACC-eu-west-1-duo-healthdump/fbduo/status/$UUID/$LATEST version.txt && jq -r '.version | "\(.[2]).\(.[1]).\(.[0])"' version.txt && rm version.txt` | |
fi | |
BOOTLOADER="2.0.0" | |
else | |
FIRMWARE=`echo $STATUS | jq -r '.application'` | |
BOOTLOADER=`echo $STATUS | jq -r '.bootloader'` | |
WIFI=`echo $STATUS | jq -r '.wifi // empty'` | |
fi | |
UPDATE_EXPR="$UPDATE_EXPR, firmwareVersions = :firmwareVersions" | |
EXPR_ATTR_VALUES="$EXPR_ATTR_VALUES,\":firmwareVersions\":{\"M\":{\"application\":{\"S\":\"$FIRMWARE\"},\"bootloader\":{\"S\":\"$BOOTLOADER\"}" | |
if [[ ! -z "$WIFI" ]]; then | |
EXPR_ATTR_VALUES="$EXPR_ATTR_VALUES,\"wifi\":{\"S\":\"$WIFI\"}" | |
fi | |
EXPR_ATTR_VALUES="$EXPR_ATTR_VALUES}}" | |
fi | |
EXPR_ATTR_VALUES="$EXPR_ATTR_VALUES}" | |
if [[ $DRY_RUN == "1" ]]; then | |
echo -e "\n" | |
# echo $UPDATE_EXPR | |
echo $EXPR_ATTR_VALUES | |
echo -e "\n" | |
else | |
aws dynamodb update-item --table-name Devices --key "{\"uuid\": {\"S\": \"$UUID\"}}" --update-expression "$UPDATE_EXPR" --expression-attribute-values "$EXPR_ATTR_VALUES" | |
fi | |
if [ $? -ne 0 ]; then | |
echo -e "\xE2\x9D\x8C" | |
else | |
echo -e "\xE2\x9C\x94" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment