diff --git a/examples/aws_lambda/lambda_handler.py b/examples/aws_lambda/lambda_handler.py new file mode 100644 index 000000000..1c45640ac --- /dev/null +++ b/examples/aws_lambda/lambda_handler.py @@ -0,0 +1,129 @@ +# _ __ +# | |/ /___ ___ _ __ ___ _ _ ® +# | ' Optional[str] + user_report_cmd = UserReportCommand() + user_report_data = user_report_cmd.execute(params, format='json') + data = json.loads(user_report_data) + users = {x['email']: x for x in data} + security_audit_report = SecurityAuditReportCommand() + security_audit_report_data = security_audit_report.execute(params, format='json') + if security_audit_report_data: + data = json.loads(security_audit_report_data) + for x in data: + if 'email' in x: + email = x['email'] + if email in users: + user = users[email] + for key in x: + if key not in user: + if key not in ('node_path', 'username'): + user[key] = x[key] + else: + users[email] = x + + return json.dumps(list(users.values()), indent=2) + + +# Email report data (as JSON attachment) to recipient specified in this Lambda +# function's environment variables +def email_result(report): + sender = os.environ.get('KEEPER_SENDER') + sendto = os.environ.get('KEEPER_SENDTO') + region = 'us-east-1' + ses_client = boto3.client('ses', region_name=region) + + message = MIMEMultipart('mixed') + message['Subject'] = 'Keeper Commander User Security Report With CSV (attached)' + message['To'] = sendto + message['From'] = sender + now = datetime.datetime.now() + + body = MIMEText(f'User Report Output created and sent at {now}', 'plain') + message.attach(body) + + attachment = MIMEApplication(report) + attachment.add_header( + 'Content-Disposition', + 'attachment', + filename='user-report.json' + ) + message.attach(attachment) + + response = ses_client.send_raw_email( + Source=message['From'], + Destinations=[sendto], + RawMessage={'Data': message.as_string()} + ) + + return response + + +# Get required Commander parameters from Lambda's environment variables (in "Configuration") +def get_params(): + user = os.environ.get('KEEPER_USER') + pw = os.environ.get('KEEPER_PASSWORD') + server = os.environ.get('KEEPER_SERVER') + private_key = os.environ.get('KEEPER_PRIVATE_KEY') + token = os.environ.get('KEEPER_DEVICE_TOKEN') + my_params = KeeperParams() + my_params.user = user + my_params.password = pw + my_params.server = server + my_params.device_private_key = private_key + my_params.device_token = token + return my_params + diff --git a/examples/aws_lambda/package_layer_content.sh b/examples/aws_lambda/package_layer_content.sh new file mode 100644 index 000000000..603983e41 --- /dev/null +++ b/examples/aws_lambda/package_layer_content.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# To create a `keepercommander` dependency layer for your AWS Lambda function : +# 1. Upload this script to any folder in your CloudShell environment. +# 2. (Optional) Upload your project's `requirements.txt` file to the same folder. +# 3. In that folder, run +# source ./package_layer_content.sh +# 4. There should now be a file named `commander-layer.zip` that can be uploaded +# to your S3 bucket, where it can then be used to create a new Lambda layer + +MAX_LIB_SIZE=262144000 +LAYER_FILENAME='commander-layer.zip' +LAYER_PATH=$(pwd)/$LAYER_FILENAME +LIB_DIR='python' +VENV='commander-venv' +OTHER_DEPS='requirements.txt' + +# Clean up previous artifacts +test -f $LAYER_FILENAME && rm $LAYER_FILENAME +test -d $LIB_DIR && rm -rf $LIB_DIR +test -d $VENV && rm -rf $VENV + +# Create package folder to zip +mkdir $LIB_DIR + +# Create and run virtual environment +python -m venv $VENV +source ./$VENV/bin/activate + +# Install dependencies and package +pip install cryptography --platform manylinux2014_x86_64 --only-binary=:all: -t $LIB_DIR +pip install keepercommander -t $LIB_DIR + +if test -f $OTHER_DEPS; then + pip install -r $OTHER_DEPS -t $LIB_DIR +fi + +deactivate + +# Check uncompressed library size +LIB_SIZE=$(du -sb $LIB_DIR | cut -f 1) +LIB_SIZE_MB=$(du -sm $LIB_DIR | cut -f 1) + +if [ "$LIB_SIZE" -ge $MAX_LIB_SIZE ]; then + echo "*****************************************************************************************************************" + echo 'Operation was aborted' + echo "The resulting layer has too many dependencies and its size ($LIB_SIZE_MB MB) exceeds the maximum allowed (~262 MB)." + echo 'Try breaking up your dependencies into smaller groups and package them as separate layers.' + echo "*****************************************************************************************************************" +else + zip -r $LAYER_FILENAME $LIB_DIR + echo "***************************************************************************" + echo "***************************************************************************" + echo 'Lambda layer file has been created' + printf "To download, copy the following file path: %s\n%s\n$LAYER_PATH%s\n%s\n" + echo 'and click on "Actions" in the upper-right corner of your CloudShell console' + echo "***************************************************************************" +fi + +# Clean-up +rm -rf $LIB_DIR +rm -rf $VENV