{"size": 3766, "ext": "js", "max_stars_repo_path": "lib/awscli.js", "max_stars_repo_name": "rlyle/serverless-aws-batch", "max_stars_repo_stars_event_min_datetime": "2019-07-24T21:35:51.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-13T14:45:03.000Z", "max_issues_repo_path": "lib/awscli.js", "max_issues_repo_name": "rlyle/serverless-aws-batch", "max_issues_repo_issues_event_min_datetime": "2019-10-09T22:19:34.000Z", "max_issues_repo_issues_event_max_datetime": "2021-11-16T11:13:01.000Z", "max_forks_repo_path": "lib/awscli.js", "max_forks_repo_name": "rlyle/serverless-aws-batch", "max_forks_repo_forks_event_min_datetime": "2019-08-09T15:22:28.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-08T20:59:29.000Z"}
{"max_stars_count": 25, "max_issues_count": 17, "max_forks_count": 21, "avg_line_length": 34.8703703704, "max_line_length": 124, "alphanum_fraction": 0.6038236856}
const { spawnSync } = require('child_process');
const fse = require('fs-extra');
const path = require('path');
const util = require('util');
const _ = require('lodash');

/**
 * Helper function to run an AWS CLI command
 * @param {string[]} options
 * @return {Object}
 */
function awsCommand(options) {
    const cmd = 'aws';
    const ps = spawnSync(cmd, options, { encoding: 'utf-8' });
    if (ps.error) {
        if (ps.error.code === 'ENOENT') {
            throw new Error('aws cli not found! Please install it.');
        }
        throw new Error(ps.error);
    } else if (ps.status !== 0) {
        throw new Error(ps.stderr);
    }
    return ps;
}

/**
 * Uses the AWS CLI to generate a pre-authenticated docker command that can be
 * used to login to the Elastic Container Registry (ECR) from docker.
 *
 * @return {string} login -u AWS -p <password> https://<account_id>.dkr.ecr.<region>.amazonaws.com
 */
function getDockerLoginToECRCommand() {
    const awsCliVersion = awsCommand(['--version']);

    // AWS CLI v2+ doesn't support "get-login" command any more - https://github.com/aws/aws-cli/issues/2875
    if (awsCliVersion.stdout.trim().indexOf('aws-cli/2') >= 0) {
        const passwordResult = awsCommand(['ecr', 'get-login-password', '--region', this.options.region]);
        // Getting account ID
        const accountIdResult = awsCommand([
            'sts', 'get-caller-identity',
            '--region', this.options.region,
            '--query', 'Account',
            '--output', 'text',
            ...(this.options.awsProfile ? ['--profile', this.options.awsProfile] : []),
        ]);

        return 'login -u AWS -p ' + passwordResult.stdout + ' ' +
            accountIdResult.stdout.trim() + '.dkr.ecr.' + this.options.region + '.amazonaws.com';
    }

    const result = awsCommand(['ecr', 'get-login', '--region', this.options.region, '--no-include-email']);
    // AWS CLI returns the full command with "docker " out front. Remove it since we don't need it.
    return result.stdout.replace('docker ', '').replace(/[\n\r]/g, '');
}

/**
 * Deletes all of our docker images in the remote ECR registry
 */
function deleteAllDockerImagesInECR() {
    try {
        const result = awsCommand(['ecr', 'list-images', '--repository-name', this.provider.naming.getECRRepositoryName()]);
        const images = JSON.parse(result.stdout);

        this.serverless.cli.log(`Found ${images['imageIds'].length} existing ECR images. Deleting...`)

        // Delete individually instead of batch so we don't run into any CLI length limits
        _.forEach(
            images['imageIds'],
            image => {
                awsCommand([
                    'ecr', 'batch-delete-image',
                    '--repository-name', this.provider.naming.getECRRepositoryName(),
                    '--image-ids', `imageDigest=${image['imageDigest']}`
                ]);
            }
        );
    }
    catch (e) {
        // If we failed to delete the stack from a previous "sls-remove" attempt, but already deleted the repository
        if (e.message.indexOf("RepositoryNotFoundException") > -1) {
            this.serverless.cli.log("ECR Repository already deleted");
        }
        // Unknown error
        else {
            throw e;
        }
    }
}

/**
 * Calls AWS CLI to get the accountID of the calling user
 * @returns {string} The accountID of the calling user
 */
let awsAccountID = null;
function getAWSAccountID() {
    if (awsAccountID == null) {
        const result = awsCommand(['sts', 'get-caller-identity']);
        awsAccountID = JSON.parse(result.stdout).Account
    }
    return awsAccountID;
}

module.exports = {
    getDockerLoginToECRCommand,
    getAWSAccountID,
    deleteAllDockerImagesInECR
};
