diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..b0464de10 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +account-data +docs \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9355e5c10..d7a14bda2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vscode config.json config/ .DS_Store @@ -15,3 +16,9 @@ data/ private_commands/ output/ .vscode/ +Pipfile.lock +auditor/node_modules +auditor/.cdk.staging +auditor/cdk.out +auditor/.env +auditor/resources/cloudmapper \ No newline at end of file diff --git a/README.md b/README.md index 889ebe4c0..0a2e5ea13 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,9 @@ python cloudmapper.py webserver --public You should then be able to view the report by visiting http://127.0.0.1:8000/account-data/report.html +# Running CloudMapper regularly to audit your environment +A CDK app for deploying CloudMapper via Fargate so that it runs nightly, sends audit findings as alerts to a Slack channel, and generating a report that is saved on S3, is described [here](auditor/README.md). + # Alternatives For network diagrams, you may want to try https://github.com/lyft/cartography or https://github.com/anaynayak/aws-security-viz diff --git a/auditor/.npmignore b/auditor/.npmignore new file mode 100644 index 000000000..5de422a0b --- /dev/null +++ b/auditor/.npmignore @@ -0,0 +1,3 @@ +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/auditor/README.md b/auditor/README.md new file mode 100644 index 000000000..277d49acd --- /dev/null +++ b/auditor/README.md @@ -0,0 +1,45 @@ +The purpose of this project is to run CloudMapper's collection and audit capabilities nightly, across multiple accounts, sending any audit findings to a Slack channel and keeping a copy of the collected metadata in an S3 bucket. + +Diagram + + +# Setup +- Clone the required projects and install the necessary modules for CDK deployment: +``` +git clone https://github.com/duo-labs/cloudmapper.git +cd cloudmapper/auditor +# Clone CloudMapper again into the auditor (weird, I know, but the only way to keep this all one repo) +git clone https://github.com/duo-labs/cloudmapper.git resources/cloudmapper +npm install +``` + +- Create an S3 bucket in your account, we'll call `MYCOMPANY-cloudmapper` +- Get a webhook to write to your slack channel and create the Secrets Manager secret `cloudmapper-slack-webhook` with it as follows: +``` +aws secretsmanager create-secret --name cloudmapper-slack-webhook --secret-string '{"webhook":"https://hooks.slack.com/services/XXX/YYY/ZZZ"}' +``` +- Create an SNS for alarms to go to if errors are encountered. +- Create roles in your other accounts with `SecurityAudit` and `ViewOnlyAccess` privileges and IAM trust policies that allow this account to assume them. +- Edit the files in `s3_bucket_files` and copy them to your S3 bucket. + - `config`: This is the containers `~/.aws/config` that will be used to assume roles in other accounts. These must be named CloudMapper. Note that the `credential_source` is set to `EcsContainer`. + - `config.json`: CloudMapper config file for specifying the accounts. + - `audit_config_override.yaml`: CloudMapper config file for muting audit findings. + - `run_cloudmapper.sh`: script for executing CloudMapper and should be unchanged. + - `cdk_app.yaml`: config for the CDK, only used during deploy. +- Deploy this CDK app: +``` +cdk deploy +``` + +# Daily use +Before setting this up to run against an account, you should manually run CloudMapper's audit or report command on the account to determine which findings should be fixed in the account, or muted. This is done to avoid having your Slack channel flooded with 100 findings. If you are not fixing or muting issues, the value of this tool will quickly deteriorate. It does not keep track of issues it previously alerted you about, so it will repeatedly alert on the same problems if action is not taken. The expectation is you should be receiving a handful or less of alerts each day (ideally zero). If that is not the case, this tool is not being used as intended and you will not get value out of it. + +To mute issues, you should modify `audit_config_override.yaml` in the S3 bucket. To test your changes, you can download the `account-data` from the S3 bucket and run CloudMapper's `audit` command to ensure the filtering works as intended. + +To add new accounts, you should first manually run CloudMapper's audit and fix/mute issues as needed. After that, add the account to the `config.json` and `config` files in the S3 bucket, along with setting up the necessary trust relationship. + +## Kicking off a manual scan +To kick off a manual scan, without needing to wait until the scheduled time, run: +``` +aws events put-events --entries '[{"Source":"cloudmapper","DetailType":"start","Detail":"{}"}]' +``` \ No newline at end of file diff --git a/auditor/bin/cloudmapperauditor.js b/auditor/bin/cloudmapperauditor.js new file mode 100644 index 000000000..48580c201 --- /dev/null +++ b/auditor/bin/cloudmapperauditor.js @@ -0,0 +1,9 @@ +#!/usr/bin/env node + +// @ts-ignore: Cannot find declaration file +require('source-map-support/register'); +const cdk = require('@aws-cdk/core'); +const { CloudmapperauditorStack } = require('../lib/cloudmapperauditor-stack'); + +const app = new cdk.App(); +new CloudmapperauditorStack(app, 'CloudmapperauditorStack'); diff --git a/auditor/cdk.json b/auditor/cdk.json new file mode 100644 index 000000000..5a4255f14 --- /dev/null +++ b/auditor/cdk.json @@ -0,0 +1,3 @@ +{ + "app": "node bin/cloudmapperauditor.js" +} diff --git a/auditor/lib/cloudmapperauditor-stack.js b/auditor/lib/cloudmapperauditor-stack.js new file mode 100644 index 000000000..ae8a3c0a8 --- /dev/null +++ b/auditor/lib/cloudmapperauditor-stack.js @@ -0,0 +1,205 @@ +/** + * Deploys the CloudMapper audit app. + * Usage: cdk deploy -c s3_bucket=MYCOMPANY-cloudmapper -c sns_topic=email + */ + +const cdk = require('@aws-cdk/core'); +const ecs = require('@aws-cdk/aws-ecs'); +const ecsPatterns = require('@aws-cdk/aws-ecs-patterns'); +const ec2 = require('@aws-cdk/aws-ec2'); +const logs = require('@aws-cdk/aws-logs'); +const iam = require('@aws-cdk/aws-iam'); +const events = require('@aws-cdk/aws-events'); +const targets = require('@aws-cdk/aws-events-targets'); +const cloudwatch = require('@aws-cdk/aws-cloudwatch'); +const cloudwatch_actions = require('@aws-cdk/aws-cloudwatch-actions'); +const sns = require('@aws-cdk/aws-sns'); +const sns_subscription = require('@aws-cdk/aws-sns-subscriptions'); +const lambda = require('@aws-cdk/aws-lambda'); + +// Import libraries to read a config file +const yaml = require('js-yaml'); +const fs = require('fs'); + +class CloudmapperauditorStack extends cdk.Stack { + /** + * + * @param {cdk.Construct} scope + * @param {string} id + * @param {cdk.StackProps=} props + */ + constructor(scope, id, props) { + super(scope, id, props); + + // Load config file + var config = yaml.safeLoad(fs.readFileSync('./s3_bucket_files/cdk_app.yaml', 'utf8')); + + if (config['s3_bucket'] == 'MYCOMPANY-cloudmapper') { + console.log("You must configure the CDK app by editing ./s3_bucket_files/cdk_app.yaml"); + process.exit(1); + } + + // Create VPC to run everything in, but without a NAT gateway. + // We want to run in a public subnet, but the CDK creates a private subnet + // by default, which results in the use of a NAT gateway, which costs $30/mo. + // To avoid that unnecessary charge, we have to create the VPC in a complicated + // way. + // This trick was figured out by jeshan in https://github.com/aws/aws-cdk/issues/1305#issuecomment-525474540 + // Normally, the CDK does not allow this because the private subnets have to have + // a route out, and you can't get rid of the private subnets. + // So the trick is to remove the routes out. + // The private subnets remain, but are not usable and have no costs. + const vpc = new ec2.Vpc(this, 'CloudMapperVpc', { + maxAzs: 2, + natGateways: 0 + }); + + // Create a condition that will always fail. + // We will use this in a moment to remove the routes. + var exclude_condition = new cdk.CfnCondition(this, + 'exclude-default-route-subnet', + { + // Checks if true == false, so this always fails + expression: cdk.Fn.conditionEquals(true, false) + } + ); + + // For the private subnets, add a CloudFormation condition to the routes + // to cause them to not be created. + for (var subnet of vpc.privateSubnets) { + for (var child of subnet.node.children) { + if (child.constructor.name==="CfnRoute") { + child.cfnOptions.condition = exclude_condition + } + } + } + + // Define the ECS task + const cluster = new ecs.Cluster(this, 'Cluster', { vpc }); + + const taskDefinition = new ecs.FargateTaskDefinition(this, 'taskDefinition', {}); + + taskDefinition.addContainer('cloudmapper-container', { + image: ecs.ContainerImage.fromAsset('./resources'), + memoryLimitMiB: 512, + cpu: 256, + environment: { + S3_BUCKET: config['s3_bucket'] + }, + logging: new ecs.AwsLogDriver({ + streamPrefix: 'cloudmapper', + logRetention: logs.RetentionDays.TWO_WEEKS + }) + }); + + // Grant the ability to assume the IAM role in any account + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + resources: ["arn:aws:iam::*:role/"+config['iam_role']], + actions: ['sts:AssumeRole'] + })); + + // Grant the ability to read and write the files from the S3 bucket + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + resources: ["arn:aws:s3:::"+config['s3_bucket']], + actions: ['s3:ListBucket'] + })); + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + resources: ["arn:aws:s3:::"+config['s3_bucket']+"/*"], + actions: ['s3:GetObject','s3:PutObject', 's3:DeleteObject'] + })); + + // Grant the ability to record the stdout to CloudWatch Logs + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + resources: ["*"], + actions: ['logs:*'] + })); + + // Grant the ability to record error and success metrics + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + // This IAM privilege has no paths or conditions + resources: ["*"], + actions: ['cloudwatch:PutMetricData'] + })); + + // Grant the ability to read from Secrets Manager + taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({ + // This IAM privilege has no paths or conditions + resources: ["*"], + actions: ['secretsmanager:GetSecretValue'], + conditions: {'ForAnyValue:StringLike':{'secretsmanager:SecretId': '*cloudmapper-slack-webhook*'}} + })); + + // Create rule to trigger this be run every 24 hours + new events.Rule(this, "scheduled_run", { + ruleName: "cloudmapper_scheduler", + // Run at 2am EST (6am UTC) every night + schedule: events.Schedule.expression("cron(0 6 * * ? *)"), + description: "Starts the CloudMapper auditing task every night", + targets: [new targets.EcsTask({ + cluster: cluster, + taskDefinition: taskDefinition, + subnetSelection: {subnetType: ec2.SubnetType.PUBLIC} + })] + }); + + // Create rule to trigger this manually + new events.Rule(this, "manual_run", { + ruleName: "cloudmapper_manual_run", + eventPattern: {source: ['cloudmapper']}, + description: "Allows CloudMapper auditing to be manually started", + targets: [new targets.EcsTask({ + cluster: cluster, + taskDefinition: taskDefinition, + subnetSelection: {subnetType: ec2.SubnetType.PUBLIC} + })] + }); + + // Create alarm for any errors + const error_alarm = new cloudwatch.Alarm(this, "error_alarm", { + metric: new cloudwatch.Metric({ + namespace: 'cloudmapper', + metricName: "errors", + statistic: "Sum" + }), + threshold: 0, + evaluationPeriods: 1, + datapointsToAlarm: 1, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + alarmDescription: "Detect errors", + alarmName: "cloudmapper_errors" + }); + + // Create SNS for alarms to be sent to + const sns_topic = new sns.Topic(this, 'cloudmapper_alarm', { + displayName: 'cloudmapper_alarm' + }); + + // Connect the alarm to the SNS + error_alarm.addAlarmAction(new cloudwatch_actions.SnsAction(sns_topic)); + + // Create Lambda to forward alarms + const alarm_forwarder = new lambda.Function(this, "alarm_forwarder", { + runtime: lambda.Runtime.PYTHON_3_7, + code: lambda.Code.asset("resources/alarm_forwarder"), + handler: "main.handler", + description: "Forwards alarms from the local SNS to another", + logRetention: logs.RetentionDays.TWO_WEEKS, + timeout: cdk.Duration.seconds(30), + memorySize: 128, + environment: { + "ALARM_SNS": config['alarm_sns_arn'] + }, + }); + + // Add priv to publish the events so the alarms can be forwarded + alarm_forwarder.addToRolePolicy(new iam.PolicyStatement({ + resources: [config['alarm_sns_arn']], + actions: ['sns:Publish'] + })); + + // Connect the SNS to the Lambda + sns_topic.addSubscription(new sns_subscription.LambdaSubscription(alarm_forwarder)); + } +} + +module.exports = { CloudmapperauditorStack } diff --git a/auditor/package-lock.json b/auditor/package-lock.json new file mode 100644 index 000000000..853a35ef3 --- /dev/null +++ b/auditor/package-lock.json @@ -0,0 +1,2565 @@ +{ + "name": "cloudmapperauditor", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@aws-cdk/assets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/assets/-/assets-1.7.0.tgz", + "integrity": "sha512-KEjWF+5F3yo3I6dRQT12tV9d0wiJcns/8OH9Gk4hwGPIGK4y7v7iFBGWSlYST4dbKKZcceX/rGw23e812exfWg==", + "requires": { + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@aws-cdk/aws-apigateway": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigateway/-/aws-apigateway-1.7.0.tgz", + "integrity": "sha512-HGVOTpGW/dlsILTrEG9o1TUtZv5EsO1OodVPKyfqLyptxIwI39CkNHqAhYwmQj/xJ/Bh54fdHM1tnx9JrRpo4A==", + "requires": { + "@aws-cdk/aws-certificatemanager": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-applicationautoscaling": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-applicationautoscaling/-/aws-applicationautoscaling-1.7.0.tgz", + "integrity": "sha512-a2gpAj2TSWhyjZ69QnJ5Hsj+6o8zrhRvhz1cZra43YF6f7QAE9bsUCu6N6E6FncwtfMoqzex94wSE41LyxeF9g==", + "requires": { + "@aws-cdk/aws-autoscaling-common": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-autoscaling": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling/-/aws-autoscaling-1.7.0.tgz", + "integrity": "sha512-y7Q5Q4J9/5pzWYPnDsuZlctDtC9+lGd8c0rFlAUH8+hGPMzEi/d9C4PUWEjZkgbnTJQ/4yksW0GXCNuCuuCYZw==", + "requires": { + "@aws-cdk/aws-autoscaling-common": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancing": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-autoscaling-common": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-common/-/aws-autoscaling-common-1.7.0.tgz", + "integrity": "sha512-GoD/Hzf6XgQIt20GeaEMceTLIs0kn9tsK1hcSs8gzDKg2FuiH3cFNYtk1tKDSb/o//6uRtUG8+LIuA4iRgQz2Q==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-autoscaling-hooktargets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-hooktargets/-/aws-autoscaling-hooktargets-1.7.0.tgz", + "integrity": "sha512-auhGz2JRtSPKhLkeYpvneeT/AK2nizs5F8vUaNdH81cxK5TlP5CMQ4rCSCVVcsAnQQ5Yu4MX6tKZwe2JgfGTCg==", + "requires": { + "@aws-cdk/aws-autoscaling": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/aws-sns-subscriptions": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-certificatemanager": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-certificatemanager/-/aws-certificatemanager-1.7.0.tgz", + "integrity": "sha512-9MrbKSZPuqU3mNtTjMIcOBHvJ26b+DPH7CykIxokTjWxckevWDpvDSKlGalvcEVtkH82ptj0PtUVZ62aMTykyQ==", + "requires": { + "@aws-cdk/aws-cloudformation": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-route53": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-cloudformation": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudformation/-/aws-cloudformation-1.7.0.tgz", + "integrity": "sha512-IGM+OEGmYNl/lNiu1IuWBU/mcQcn1wf4mD/z4ktIxWmdBtOV/OxVDa5cYjA5Vk7N44b7b5fmFb4Sc+L0R68jQw==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-cloudfront": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudfront/-/aws-cloudfront-1.7.0.tgz", + "integrity": "sha512-EgShd1CIwE8nc+v0qmEcUqQxuTJsM2ELwF3sY9MQM7AIXHvefvNJ5vL2uj4+5Ns9i2G7QSKSGau2GSWr/y/9pA==", + "requires": { + "@aws-cdk/aws-certificatemanager": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-cloudwatch": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudwatch/-/aws-cloudwatch-1.7.0.tgz", + "integrity": "sha512-8OrF7+8vV2BrFlZ5f31lj2eG1CMTeSyzBbUpy5o/6YvklljrXM4izxounFDTySwUK4nWmi9rswoNMaDOXUOOmQ==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-cloudwatch-actions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudwatch-actions/-/aws-cloudwatch-actions-1.7.0.tgz", + "integrity": "sha512-6IRrmszrLBavluBRGqjz5z64bGXvc6e4clzO4SgMDvLK/MBodRuDk6hy3fgbIXKqdrAqMSPXBSjz7qN6syHD0Q==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "^1.7.0", + "@aws-cdk/aws-autoscaling": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-codebuild": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codebuild/-/aws-codebuild-1.7.0.tgz", + "integrity": "sha512-XXgci7uHcJaxGKfXNgZvKJxRdl6KC26dDmT4zYvLm3hC12WZYIbQcyBsr3IeGLdpMEHJZwNhy2bQXwq2DnsMsw==", + "requires": { + "@aws-cdk/assets": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-codecommit": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-ecr": "^1.7.0", + "@aws-cdk/aws-ecr-assets": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/aws-s3-assets": "^1.7.0", + "@aws-cdk/aws-secretsmanager": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-codecommit": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codecommit/-/aws-codecommit-1.7.0.tgz", + "integrity": "sha512-JDcwubtnOLHM2trphP3FgFtReZH5ig0wOtxpChJMerSNQcwHXrkFH1O+Zj21HUmTddVTo9AvOKuSluU14rCYxg==", + "requires": { + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-codepipeline": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codepipeline/-/aws-codepipeline-1.7.0.tgz", + "integrity": "sha512-gjsQH3fQqLAS3r/XW7XBKxIW6pTF+TtpVIHkfr9aD7+LAXtmH1XH4NXywzflUL3iyy0h/H10yrw5e9pzMElHdQ==", + "requires": { + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-ec2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ec2/-/aws-ec2-1.7.0.tgz", + "integrity": "sha512-P87pdA+b5NihUghiBwKqagOOtjrsv3SPa2RDpNJL+k0RXvOI1L0+LgqAt5s4reUiTGPABki+GSPPhDVCisZ6Fg==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-ssm": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-ecr": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr/-/aws-ecr-1.7.0.tgz", + "integrity": "sha512-YyUrF3DHkVTTJCVs5aS/xSWwZCxCLA52xNewrNigasuPxaiLevnGV82DLQj3YLu84k9M5wp9zeO9Mi7vcmEltg==", + "requires": { + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-ecr-assets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr-assets/-/aws-ecr-assets-1.7.0.tgz", + "integrity": "sha512-1YrkN7MAbZwHIYLhw6743Ccf9kCRRv6KsHgqYMmzYGnLdvhG+1Nx6/3Jr45eJOcCQk1XLeP3AH4yvmoCDxGxOw==", + "requires": { + "@aws-cdk/assets": "^1.7.0", + "@aws-cdk/aws-cloudformation": "^1.7.0", + "@aws-cdk/aws-ecr": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-ecs": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecs/-/aws-ecs-1.7.0.tgz", + "integrity": "sha512-O1JAesmBib1X2aDV8aG2sEWBMXkWxMhVi5rq2LagujF/WhZgkTro+8dUZKA+WGpGef2M9ENt2Gi62ZRjacGJJg==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "^1.7.0", + "@aws-cdk/aws-autoscaling": "^1.7.0", + "@aws-cdk/aws-autoscaling-hooktargets": "^1.7.0", + "@aws-cdk/aws-certificatemanager": "^1.7.0", + "@aws-cdk/aws-cloudformation": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-ecr": "^1.7.0", + "@aws-cdk/aws-ecr-assets": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancing": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-logs": "^1.7.0", + "@aws-cdk/aws-route53": "^1.7.0", + "@aws-cdk/aws-route53-targets": "^1.7.0", + "@aws-cdk/aws-secretsmanager": "^1.7.0", + "@aws-cdk/aws-servicediscovery": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/aws-ssm": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-ecs-patterns": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecs-patterns/-/aws-ecs-patterns-1.7.0.tgz", + "integrity": "sha512-Fg+Z1lMk2txWU/isYM4LlK9kVIOdwMoCBEnYWXWRmVdTx+1i7+tau3EcfkXx9SN+BoMR4IxRovJmGsVv/BRIOg==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "^1.7.0", + "@aws-cdk/aws-certificatemanager": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-ecs": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-events-targets": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-route53": "^1.7.0", + "@aws-cdk/aws-route53-targets": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-elasticloadbalancing": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancing/-/aws-elasticloadbalancing-1.7.0.tgz", + "integrity": "sha512-ktuRLZeR5+yVRbbYHUi82fU82DCzzBB//M/9wKFD1NDfQKr2wi4g4ZzFe6Z1GBxrcWFyzwS0DZHYSK3n/v6vfA==", + "requires": { + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-elasticloadbalancingv2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancingv2/-/aws-elasticloadbalancingv2-1.7.0.tgz", + "integrity": "sha512-NLh8Vpc5ARFHih6OA5jzMVxjqq3+zpdI4PhaUyxtFL2Vx4UTxPbkWZ9PkcxUShZLk0L8Xr1rANEFFZa5SIX+JA==", + "requires": { + "@aws-cdk/aws-certificatemanager": "^1.7.0", + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-events": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-events/-/aws-events-1.7.0.tgz", + "integrity": "sha512-7rC2ie7AAVo4awvv9wvGKYlLIkDfoPSChdyrCTBf5xc22MIO3r0Qlrr2yTIjA35K8JT15fdlKbV+PN4+ez0WYA==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-events-targets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-events-targets/-/aws-events-targets-1.7.0.tgz", + "integrity": "sha512-QmaHtZSQmWbxc9cnKSD8fQcGWCuX0JllsdnMCYAM/K3WhlG12LDtkSlXnZU2TCWLcZASafVzg1IWvHFtKM8nWA==", + "requires": { + "@aws-cdk/aws-cloudformation": "^1.7.0", + "@aws-cdk/aws-codebuild": "^1.7.0", + "@aws-cdk/aws-codepipeline": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-ecs": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/aws-sns-subscriptions": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/aws-stepfunctions": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/custom-resources": "^1.7.0" + } + }, + "@aws-cdk/aws-iam": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-iam/-/aws-iam-1.7.0.tgz", + "integrity": "sha512-nOMtQeR7WZ3IqRkw8B5HuRVdvuFGEjBCwK9ImAYdVJcOVGAejZ6QQOiOGgA6rcUE0V0srahbOGKeeBF4rhCLPA==", + "requires": { + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/region-info": "^1.7.0" + } + }, + "@aws-cdk/aws-kms": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-kms/-/aws-kms-1.7.0.tgz", + "integrity": "sha512-X4Jok5TkJCk33HHXPLnVAEqo8kXfWfA73iYlTlSNm5BigDYIrTtHVqGWiSKQdl8pKPN01I+IG8N339kRmbJuNw==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-lambda": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda/-/aws-lambda-1.7.0.tgz", + "integrity": "sha512-DANjzpBZgw7+H/HgolZdr7lqkY5702CdSAL/ozkDTjfnfuAcbBskBoZ3XRl9EMfp1CL4grRWNB4K1+MYKPGoxw==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-logs": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/aws-s3-assets": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-logs": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-logs/-/aws-logs-1.7.0.tgz", + "integrity": "sha512-iq34gt1rlAKoB1+Vq3QQFN69GTjocY4E2w1JKnu6zk8sSvN3sMLb1kRIH1/dTYZNBwHbXgc3K0G9y1JqOnI7iQ==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-route53": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53/-/aws-route53-1.7.0.tgz", + "integrity": "sha512-QVDv2LNYp1tViP9cp3entCTdc9sgQMrZ87W16lfjwKnzMZTdIN+/Lm2/BKN6tGOI/7WIcocQolaEDeZjQ1zh/Q==", + "requires": { + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-logs": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-route53-targets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53-targets/-/aws-route53-targets-1.7.0.tgz", + "integrity": "sha512-g7++uIKHi62ZRmpgZEXNwKTL52Kk2hEkchKY04XPJ3uxnvinRnqBmtjm16/KgsqIxCi0ii9WTiO9JPJWopMV3g==", + "requires": { + "@aws-cdk/aws-apigateway": "^1.7.0", + "@aws-cdk/aws-cloudfront": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancing": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-route53": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/region-info": "^1.7.0" + } + }, + "@aws-cdk/aws-s3": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3/-/aws-s3-1.7.0.tgz", + "integrity": "sha512-yUeDnDPszbEOa/XGOc7Ear0NguRYv53xy+bGJDDzD1jNCWQZ45pvCkMZrcLKSJlH4+L1Dbv0Oc0OQlSe6jlp9Q==", + "requires": { + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-s3-assets": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3-assets/-/aws-s3-assets-1.7.0.tgz", + "integrity": "sha512-OE1ektTDAHfFNlEpd8a8CFHGMmrfCUo09vJOfsxUrAxiAI5fzenNtajAJWsfmZ8fOTsVFGgsAcL851/bzDnsEg==", + "requires": { + "@aws-cdk/assets": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-secretsmanager": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-secretsmanager/-/aws-secretsmanager-1.7.0.tgz", + "integrity": "sha512-INX0WUCgpbJHbB2oVY4PetcRoFpjBHh7AJ+pmCafaNdyN1vin+FnPQGX9SmsLBSRagGXGs3aEuFFfMsoPoIq3w==", + "requires": { + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-servicediscovery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicediscovery/-/aws-servicediscovery-1.7.0.tgz", + "integrity": "sha512-rYI5yZEN3F2cZU7gZvjzsFAdu1sgZMPqSGxxcy9JU2oikg7CTwAvr3Y0/sU8k9vUwXt1mSbMfwmvUIA7dWdOZg==", + "requires": { + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-elasticloadbalancingv2": "^1.7.0", + "@aws-cdk/aws-route53": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-sns": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns/-/aws-sns-1.7.0.tgz", + "integrity": "sha512-tGZHWlEiTpZHvDO48DdCuF+hov9JUNpeR3dRInrn5N5QWMPN6jxetqSruj7NsAmqBvszAJFEtJN/XAJYlDAjqw==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-sns-subscriptions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns-subscriptions/-/aws-sns-subscriptions-1.7.0.tgz", + "integrity": "sha512-g7co8/EA6tUNXvOOtGoRmhofRmKefqMyQJ77s+d8vUxg/X1CjvwaeXiGsI1dFlrbLT0x71hbl9Hd8mDlrMxLnA==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/aws-sqs": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-sqs": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sqs/-/aws-sqs-1.7.0.tgz", + "integrity": "sha512-oJreqOtr1HMK7DM63xuviwSHSuyqkHNR4REfuz6OXSbHsPwCnmEMoSg7F5nXVIfsPr8xPOid9bLSxR/EeN+PFw==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-kms": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/aws-ssm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ssm/-/aws-ssm-1.7.0.tgz", + "integrity": "sha512-3sGsDwKADTO0rzAUpuDf6haSLkJBGgqWCe5wvJXtzW3kwv5xWGzC8DWKt7yUxHzKLLHI4lgys43cGpEYTqp9Rg==", + "requires": { + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/aws-stepfunctions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions/-/aws-stepfunctions-1.7.0.tgz", + "integrity": "sha512-JN8+Gd2VqgJQvTmOX7F0LXVfU2eAntATsTqtahYneHwt9dWnQGFx0inGgmSO0L41QX6HX/ma+D4fNCJjVSXwGg==", + "requires": { + "@aws-cdk/aws-cloudwatch": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/cfnspec": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.7.0.tgz", + "integrity": "sha512-u/sEJAG/pKF6rzk/inpsOlCRL90nra6pBM7QsPxJjfaPhWj8i6/6t3dRBP5exhfZawwCMy9tc3Q/WYfHlMdNRg==", + "dev": true, + "requires": { + "md5": "^2.2.1" + } + }, + "@aws-cdk/cloudformation-diff": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.7.0.tgz", + "integrity": "sha512-KCBabEHkJn4AfP41Bfay/MC2b244syK5DIZeyZbSnMNfIw/+CIbKW/Mm50lPcMhLaAHvIBBbOLkUneg2v7isOA==", + "dev": true, + "requires": { + "@aws-cdk/cfnspec": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0", + "colors": "^1.3.3", + "diff": "^4.0.1", + "fast-deep-equal": "^2.0.1", + "source-map-support": "^0.5.13", + "string-width": "^4.1.0", + "table": "^5.4.6" + } + }, + "@aws-cdk/core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/core/-/core-1.7.0.tgz", + "integrity": "sha512-upkhqAhCgJJeJxZyvOFfbMDgwATKASBoC1VGPa1JBdT3QpixyxLbPZ7VwImfKtCDSefbULWu1eG+ZoXAvIUozA==", + "requires": { + "@aws-cdk/cx-api": "^1.7.0" + } + }, + "@aws-cdk/custom-resources": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/custom-resources/-/custom-resources-1.7.0.tgz", + "integrity": "sha512-2D36zEaaQL3oDWQ+3x2TjGyU+D0fuFyJVegShC9svYFyQLopnmrv7XuPw8vcMG21ZTYw32Jm77B7+rhqzE1diw==", + "requires": { + "@aws-cdk/aws-cloudformation": "^1.7.0", + "@aws-cdk/aws-iam": "^1.7.0", + "@aws-cdk/aws-lambda": "^1.7.0", + "@aws-cdk/aws-sns": "^1.7.0", + "@aws-cdk/core": "^1.7.0" + } + }, + "@aws-cdk/cx-api": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.7.0.tgz", + "integrity": "sha512-Ee+y2zScTti49Gfpttd7F2GssMrgffhC+fZ4TQIUZfuDHequRtYDRnQBsc3JbBHBYmOLxHzd8WI/KBUYl42TFA==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "bundled": true + } + } + }, + "@aws-cdk/region-info": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.7.0.tgz", + "integrity": "sha512-OiHGqMuiNB2Fd1kmfkHspICxG05J0GyO4F3g0XW02HF3Qw0ykKH6Ll1Vt11fGZSMDHLIqo4WbFOyPbHepLeLwQ==" + }, + "@babel/runtime": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/runtime-corejs2": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.6.0.tgz", + "integrity": "sha512-zbPQzlbyJab2xCYb6VaESn8Tk/XiVpQJU7WvIKiQCwlFyc2NSCzKjqtBXCvpZBbiTOHCx10s2656REVnySwb+A==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, + "@types/node": { + "version": "8.10.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.45.tgz", + "integrity": "sha512-tGVTbA+i3qfXsLbq9rEq/hezaHY55QxQLeXQL2ejNgFAxxrgu8eMmYIOsRcl7hN1uTLVsKOOYacV/rcJM3sfgQ==", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "ast-types": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.2.tgz", + "integrity": "sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-cdk": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-1.7.0.tgz", + "integrity": "sha512-7TVFQDrTR4Q2nQ4XpvXZY8eybGuqgHOaTVSUn6uw2a3qilalWJbnseZdQnOZ+nF3/Cs3HuA1Yu2TnXUIwUDinA==", + "dev": true, + "requires": { + "@aws-cdk/cloudformation-diff": "^1.7.0", + "@aws-cdk/cx-api": "^1.7.0", + "@aws-cdk/region-info": "^1.7.0", + "archiver": "^3.1.1", + "aws-sdk": "^2.524.0", + "camelcase": "^5.3.1", + "colors": "^1.3.3", + "decamelize": "^3.2.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.4", + "json-diff": "^0.5.4", + "minimatch": ">=3.0", + "promptly": "^3.0.3", + "proxy-agent": "^3.1.0", + "request": "^2.88.0", + "semver": "^6.3.0", + "source-map-support": "^0.5.13", + "table": "^5.4.6", + "yaml": "^1.6.0", + "yargs": "^14.0.0" + } + }, + "aws-sdk": { + "version": "2.524.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.524.0.tgz", + "integrity": "sha512-nCnKEExs1OqwNG6sIrRy+Lj8Zt2M6BTa6YlEMQ1gIpdwznaAN9XyTnm+MDc3iYsSl58MOBwiKpY8d6CONuxuDw==", + "dev": true, + "requires": { + "buffer": "4.9.1", + "events": "1.1.1", + "ieee754": "1.1.8", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", + "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "dev": true, + "requires": { + "readable-stream": "^3.0.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.2.tgz", + "integrity": "sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "cli-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.1.7.tgz", + "integrity": "sha1-rcMgD6RxzCEbDaf1ZrcemLnWc0c=", + "dev": true, + "requires": { + "es5-ext": "0.8.x" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-uri-to-buffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.1.tgz", + "integrity": "sha512-OkVVLrerfAKZlW2ZZ3Ve2y65jgiWqBKsTfUIAFbn8nVbPcCZg6l6gikKlEYv0kXcmzqGm6mFq/Jf2vriuEkv8A==", + "dev": true, + "requires": { + "@types/node": "^8.0.7" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "requires": { + "xregexp": "^4.2.4" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "degenerator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", + "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", + "dev": true, + "requires": { + "ast-types": "0.x.x", + "escodegen": "1.x.x", + "esprima": "3.x.x" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + }, + "difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=", + "dev": true, + "requires": { + "heap": ">= 0.2.0" + } + }, + "dreamopt": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.6.0.tgz", + "integrity": "sha1-2BPM2sjTnYrVJndVFKE92mZNa0s=", + "dev": true, + "requires": { + "wordwrap": ">=0.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "es5-ext": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.8.2.tgz", + "integrity": "sha1-q6jZ4ZQ6iVrJaDemKjmz9V7NlKs=", + "dev": true + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escodegen": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-uri": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.3.tgz", + "integrity": "sha512-x5j6Ks7FOgLD/GlvjKwgu7wdmMR55iuRHhn8hj/+gA+eSbxQvZ+AEomq+3MgVEZj1vpi738QahGbCCSIDtXtkw==", + "dev": true, + "requires": { + "data-uri-to-buffer": "2", + "debug": "4", + "extend": "~3.0.2", + "file-uri-to-path": "1", + "ftp": "~0.3.10", + "readable-stream": "3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "heap": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", + "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-diff": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.5.4.tgz", + "integrity": "sha512-q5Xmx9QXNOzOzIlMoYtLrLiu4Jl/Ce2bn0CNcv54PhyH89CI4GWlGVDye8ei2Ijt9R3U+vsWPsXpLUNob8bs8Q==", + "dev": true, + "requires": { + "cli-color": "~0.1.6", + "difflib": "~0.2.1", + "dreamopt": "~0.6.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pac-proxy-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.0.tgz", + "integrity": "sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q==", + "dev": true, + "requires": { + "agent-base": "^4.2.0", + "debug": "^3.1.0", + "get-uri": "^2.0.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "pac-resolver": "^3.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "^4.0.1" + } + }, + "pac-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", + "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "dev": true, + "requires": { + "co": "^4.6.0", + "degenerator": "^1.0.4", + "ip": "^1.1.5", + "netmask": "^1.0.6", + "thunkify": "^2.1.2" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promptly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", + "integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", + "dev": true, + "requires": { + "pify": "^3.0.0", + "read": "^1.0.4" + } + }, + "proxy-agent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.1.0.tgz", + "integrity": "sha512-IkbZL4ClW3wwBL/ABFD2zJ8iP84CY0uKMvBPk/OceQe/cEjrxzN1pMHsLwhbzUoRhG9QbSxYC+Z7LBkTiBNvrA==", + "dev": true, + "requires": { + "agent-base": "^4.2.0", + "debug": "^3.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "lru-cache": "^4.1.2", + "pac-proxy-agent": "^3.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^4.0.1" + } + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "smart-buffer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", + "dev": true + }, + "socks": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", + "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "4.0.2" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "dev": true, + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "tar-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", + "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "dev": true, + "requires": { + "bl": "^3.0.0", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "thunkify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typescript": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz", + "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + }, + "xregexp": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz", + "integrity": "sha512-sO0bYdYeJAJBcJA8g7MJJX7UrOZIfJPd8U2SC7B2Dd/J24U0aQNoGp33shCaBSWeb0rD5rh6VBUIXOkGal1TZA==", + "dev": true, + "requires": { + "@babel/runtime-corejs2": "^7.2.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yaml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.6.0.tgz", + "integrity": "sha512-iZfse3lwrJRoSlfs/9KQ9iIXxs9++RvBFVzAqbbBiFT+giYtyanevreF9r61ZTbGMgWQBxAua3FzJiniiJXWWw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5" + } + }, + "yargs": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.0.0.tgz", + "integrity": "sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + } + } + }, + "zip-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.2.tgz", + "integrity": "sha512-ykebHGa2+uzth/R4HZLkZh3XFJzivhVsjJt8bN3GvBzLaqqrUdRacu+c4QtnUgjkkQfsOuNE1JgLKMCPNmkKgg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + } + } + } +} diff --git a/auditor/package.json b/auditor/package.json new file mode 100644 index 000000000..b90639873 --- /dev/null +++ b/auditor/package.json @@ -0,0 +1,29 @@ +{ + "name": "cloudmapperauditor", + "version": "1.0.0", + "bin": { + "cloudmapperauditor": "bin/cloudmapperauditor.js" + }, + "scripts": { + "test": "tsc", + "test:watch": "tsc -w", + "cdk": "cdk" + }, + "devDependencies": { + "@types/node": "8.10.45", + "aws-cdk": "^1.7.0", + "typescript": "^3.6.2" + }, + "dependencies": { + "@aws-cdk/aws-cloudwatch-actions": "^1.7.0", + "@aws-cdk/aws-ec2": "^1.7.0", + "@aws-cdk/aws-ecs": "^1.7.0", + "@aws-cdk/aws-ecs-patterns": "^1.7.0", + "@aws-cdk/aws-events": "^1.7.0", + "@aws-cdk/aws-logs": "^1.7.0", + "@aws-cdk/aws-s3": "^1.7.0", + "@aws-cdk/core": "^1.7.0", + "js-yaml": "^3.13.1", + "source-map-support": "^0.5.13" + } +} diff --git a/auditor/resources/.dockerignore b/auditor/resources/.dockerignore new file mode 100644 index 000000000..b0464de10 --- /dev/null +++ b/auditor/resources/.dockerignore @@ -0,0 +1,3 @@ +.git +account-data +docs \ No newline at end of file diff --git a/auditor/resources/Dockerfile b/auditor/resources/Dockerfile new file mode 100644 index 000000000..667663fbf --- /dev/null +++ b/auditor/resources/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.7-slim as cloudmapper + +LABEL maintainer="https://github.com/0xdabbad00/" +LABEL Project="https://github.com/duo-labs/cloudmapper" + +WORKDIR /opt/cloudmapper +ENV AWS_DEFAULT_REGION=us-east-1 + +RUN apt-get update -y +RUN apt-get install -y build-essential autoconf automake libtool python3.7-dev python3-tk jq awscli + +COPY cloudmapper/. /opt/cloudmapper +COPY entrypoint.sh /opt/cloudmapper/entrypoint.sh + +# Remove the demo data +RUN rm -rf /opt/cloudmapper/account-data/demo + +# Install the python libraries needed for CloudMapper +RUN pip install pipenv +RUN cd /opt/cloudmapper && pipenv install --skip-lock + +ENTRYPOINT pipenv run /opt/cloudmapper/entrypoint.sh diff --git a/auditor/resources/alarm_forwarder/main.py b/auditor/resources/alarm_forwarder/main.py new file mode 100644 index 000000000..5677d1073 --- /dev/null +++ b/auditor/resources/alarm_forwarder/main.py @@ -0,0 +1,11 @@ +import boto3 +import os + +def handler(event, context): + sns = boto3.client('sns') + for record in event['Records']: + sns.publish( + TopicArn=str(os.environ['ALARM_SNS']), + Message=record['Sns']['Message'], + Subject=record['Sns']['Subject']) + return True \ No newline at end of file diff --git a/auditor/resources/entrypoint.sh b/auditor/resources/entrypoint.sh new file mode 100755 index 000000000..78e9bae7a --- /dev/null +++ b/auditor/resources/entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +aws s3 cp s3://$S3_BUCKET/run_cloudmapper.sh . +if [ $? -ne 0 ]; then + echo "ERROR: The script run_cloudmapper.sh was not found" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 + exit 1 +fi +chmod +x ./run_cloudmapper.sh +# Run the script for 3 hours before timing out +timeout --preserve-status --signal=KILL 3h ./run_cloudmapper.sh +if [ $? -ne 0 ]; then + echo "ERROR: The script timed out or errored" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 + exit 1 +fi \ No newline at end of file diff --git a/auditor/s3_bucket_files/audit_config_override.yaml b/auditor/s3_bucket_files/audit_config_override.yaml new file mode 100644 index 000000000..9a354492f --- /dev/null +++ b/auditor/s3_bucket_files/audit_config_override.yaml @@ -0,0 +1,10 @@ +# Include overrides here to the default audit_config.yaml settings. + +# # Example 1: Disable a rule entirely +# GUARDDUTY_OFF: +# severity: Mute + +# # Example 2: Ignore certain resources from the auditing +# S3_PUBLIC_POLICY_GETOBJECT_ONLY: +# # This is an array of regexes, and must match the entire string +# ignore_resources: [".*demo"] diff --git a/auditor/s3_bucket_files/cdk_app.yaml b/auditor/s3_bucket_files/cdk_app.yaml new file mode 100644 index 000000000..93e574bda --- /dev/null +++ b/auditor/s3_bucket_files/cdk_app.yaml @@ -0,0 +1,10 @@ +# This file is used for configuring the CDK app during deployment. + +# S3 bucket where these files are stored +s3_bucket: MYCOMPANY-cloudmapper + +# SNS where alarms are sent +alarm_sns_arn: "arn:aws:sns:us-east-1:000000000000:email" + +# IAM role that is assumed into in other accounts +iam_role: CloudMapper diff --git a/auditor/s3_bucket_files/config b/auditor/s3_bucket_files/config new file mode 100644 index 000000000..5c7e0c36b --- /dev/null +++ b/auditor/s3_bucket_files/config @@ -0,0 +1,5 @@ +[profile test] +region=us-east-1 +output=json +credential_source = EcsContainer +role_arn=arn:aws:iam::000000000000:role/CloudMapper diff --git a/auditor/s3_bucket_files/config.json b/auditor/s3_bucket_files/config.json new file mode 100644 index 000000000..472508772 --- /dev/null +++ b/auditor/s3_bucket_files/config.json @@ -0,0 +1,8 @@ +{ + "accounts": + [ + {"id": "000000000000", "name": "test", "default": true} + ], + "cidrs": {} +} + diff --git a/auditor/s3_bucket_files/run_cloudmapper.sh b/auditor/s3_bucket_files/run_cloudmapper.sh new file mode 100644 index 000000000..3d9a39e91 --- /dev/null +++ b/auditor/s3_bucket_files/run_cloudmapper.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +echo "Runnning run_cloudmapper" + +# Configure the AWS SDK so we can assume roles +mkdir ~/.aws +aws s3 cp s3://$S3_BUCKET/config ~/.aws/config + +# Get CloudMapper config +aws s3 cp s3://$S3_BUCKET/config.json config.json +aws s3 cp s3://$S3_BUCKET/audit_config_override.yaml config/audit_config_override.yaml + +# Get Slack webhook +export SLACK_WEBHOOK=$(aws secretsmanager get-secret-value --secret-id cloudmapper-slack-webhook | jq -cr '.SecretString|fromjson|.webhook') + +echo "Starting CloudMapper audit" | python ./utils/toslack.py + +mkdir collect_logs + +children_pids="" + +# Collect the metadata from the AWS accounts +while read account; do + # For each account, run the following function in the background + function collect { + echo "*** Collecting from $1" + python cloudmapper.py collect --profile $1 --account $1 > collect_logs/$1 + if [ $? -ne 0 ]; then + echo "ERROR: The collect command had an error for account $1" + # Record error + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 + else + # Record collection was successful + echo " Collection from $1 was successful" + # Record successful collection + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=collections,Value=1 + fi + } + collect $account & + children_pids+="$! " + echo "children pids = $children_pids" +done <<< "$(grep profile ~/.aws/config | sed 's/\[profile //' | sed 's/\]//')" + +# Wait for all the collections to finish +sleep 10 +wait $children_pids +sleep 10 + +echo "Done waiting, start audit" + +# Audit the accounts and send the alerts to Slack +python cloudmapper.py audit --accounts all --markdown | python ./utils/toslack.py +if [ $? -ne 0 ]; then + echo "ERROR: The audit command had an error" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 +fi + +echo "Generate the report" +python cloudmapper.py report --accounts all +if [ $? -ne 0 ]; then + echo "ERROR: The report command had an error" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 +fi + +# Copy the collect data to the S3 bucket +aws s3 sync --delete account-data/ s3://$S3_BUCKET/account-data/ +if [ $? -ne 0 ]; then + echo "ERROR: syncing account-data failed" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 +fi + +# Copy the logs to the S3 bucket +aws s3 sync --delete collect_logs/ s3://$S3_BUCKET/collect_logs/ +if [ $? -ne 0 ]; then + echo "ERROR: syncing the collection logs failed" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 +fi + +# Copy the report to the S3 bucket +aws s3 sync --delete web/ s3://$S3_BUCKET/web/ +if [ $? -ne 0 ]; then + echo "ERROR: syncing web directory failed" + aws cloudwatch put-metric-data --namespace cloudmapper --metric-data MetricName=errors,Value=1 +fi +echo "Completed CloudMapper audit" +echo "Completed CloudMapper audit" | python ./utils/toslack.py \ No newline at end of file diff --git a/auditor/tsconfig.json b/auditor/tsconfig.json new file mode 100644 index 000000000..45b40c310 --- /dev/null +++ b/auditor/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "lib": [ + "es2016", + "es2017.object", + "es2017.string" + ], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "allowJs": true, + "checkJs": true, + "noEmit": true + } +} diff --git a/docs/images/nightly_scanner_diagram.png b/docs/images/nightly_scanner_diagram.png new file mode 100644 index 000000000..434d2d847 Binary files /dev/null and b/docs/images/nightly_scanner_diagram.png differ