/**
* @file retrieves information about the ec2 instance and the docker container where the current process is being executed
* @author Florian Schaper <f.schaper@reply.de>
* @copyright Florian Schaper 2018, MIT License
*/
'use strict';
const queryEc2Metadata = require('./query/ec2Metadata');
const queryEcsAgentClusterName = require('./query/ecsAgentClusterName');
const queryEcsAgentCurrentTask = require('./query/ecsAgentCurrentTask');
const queryEcsCurrentTaskFromFile = require('./query/ecsCurrentTaskFromFile');
/**
* @typedef {Object} ECSTaskInformationPortInfo
* @property {string} protocol - protocol used e.g. tcp
* @property {number} container - port on the container side
* @property {number} host - port on the host side
*/
/**
* @typedef {Object} ECSTaskInformation
* @property {string} arn - aws arn uniquely identifying the task
* @property {string} cluster - name of the cluster
* @property {string} dockerId - docker id
* @property {string} containerName - name of the container
* @property {string} [publicHostname] - public dns domain name of the ec2 instance (if available)
* @property {string} [publicIpv4] - public ipv4 address of the ec2 instance (if available)
* @property {string} [localHostname] - private dns domain name of the ec2 instance (if available)
* @property {string} [localIpv4] - private ipv4 address of the ec2 instance (if available)
* @property {Array.<ECSTaskInformationPortInfo>} ports - docker to host port mapping
*/
/**
* @callback InspectHandler
* @param {Error|null} error - error that may have occurred
* @param {ECSTaskInformation} result - result of the operation
*/
/**
* provides information about the ec2/ecs instance that a docker image is currently running from
*
* @param {Object} [options] - additional options
* @param {InspectHandler} [options.callback] - optional callback which will be called with the result or an error
* @returns {Promise<ECSTaskInformation>} information about the current docker process on ecs
*/
function inspect(options) {
// combine agent cluster and task information
const queryEcsAgentInformation = () => Promise.all([
queryEcsAgentClusterName(),
queryEcsAgentCurrentTask()
]).then(result => Object.assign(...result));
const response = Promise.all([
// if the ECS_CONTAINER_METADATA_FILE environment variable has been defined,
// we try to lookup the mounted file from the docker volume otherwise we will fall back to querying the local agent
queryEcsCurrentTaskFromFile().catch(() => queryEcsAgentInformation()),
// collect additional information about the ec2 instance
queryEc2Metadata()
]).then(result => Object.assign(...result));
// if an callback has been passed we execute it for result and failure conditions
// promise rejections will be caught and passed on to the callback
if (options && typeof options.callback === 'function') {
response.then((taskInformation) => {
options.callback(null, taskInformation);
return taskInformation;
}).catch(error => options.callback(error instanceof Error ? error : new Error(error)));
}
return response;
}
module.exports = inspect;