/*
* Author: Vlad Seryakov vseryakov@gmail.com
* backendjs 2018
*/
const logger = require(__dirname + '/../logger');
const lib = require(__dirname + '/../lib');
const aws = require(__dirname + '/../aws');
/**
* AWS ECS API request
* @memberof module:aws
* @method queryECS
*/
aws.queryECS = function(action, obj, options, callback)
{
this.queryService("ecs", "AmazonEC2ContainerServiceV20141113", action, obj, options, callback);
}
/**
* @memberof module:aws
* @method ecsDescribeTasks
*/
aws.ecsDescribeTasks = function(options, callback)
{
var req = {
cluster: options.cluster || this.ecsCluster,
tasks: lib.split(options.tasks),
include: ["TAGS"],
};
aws.queryECS("DescribeTasks", req, (err, rc) => {
for (const i in rc.tasks) aws.ecsPrepareTask(rc.tasks[i]);
lib.tryCall(callback, err, rc);
});
}
/**
* @memberof module:aws
* @method ecsPrepareTask
*/
aws.ecsPrepareTask = function(task)
{
task.id = task.taskArn.split("/").pop();
task.name = task.containers[0].name;
var attrs = lib.isArray(task.attributes, []);
for (const a of attrs) {
if (a.name == 'ecs.cpu-architecture') task.arch = a.value;
}
for (const i in task.attachments) {
if (task.attachments[i].type == "ElasticNetworkInterface") {
var details = lib.isArray(task.attachments[i].details, []);
for (const d of details) {
if (d.name == 'privateIPv4Address') task.privateIpAddress = d.value; else
if (d.name == 'subnetId') task.subnetId = d.value;
}
}
}
if (task.group && task.group.startsWith("family:")) {
task.family = task.group.substr(7);
} else {
task.family = task.taskDefinitionArn.split(/[:/]/).at(-2);
}
return task;
}
/**
* @memberof module:aws
* @method ecsRunTask
*/
aws.ecsRunTask = function(options, callback)
{
var req = {
taskDefinition: options.task,
count: options.count || 1,
cluster: options.cluster || this.ecsCluster,
clientToken: options.clientToken,
enableExecuteCommand: options.enableExecuteCommand,
enableECSManagedTags: options.enableECSManagedTags,
group: options.group,
launchType: options.launchType,
capacityProviderStrategy: options.provider ? [{ capacityProvider: options.provider }] : options.capacityProviderStrategy,
networkConfiguration: options.networkConfiguration,
platformVersion: options.platformVersion,
propagateTags: options.propagateTags,
referenceId: options.referenceId,
startedBy: options.startedBy,
tags: options.tags,
placementStrategy: options.placementStrategy,
placementConstraints: options.placementConstraints,
volumeConfigurations: options.volumeConfigurations,
};
var network = {};
if (options.publicIp || this.publicIp) {
network.assignPublicIp = "ENABLED";
}
if (options.groupId || this.groupId) {
network.securityGroups = lib.split(options.groupId || this.groupId, null, { unique: 1 });
}
if (options.subnetId || this.subnetId) {
network.subnets = lib.split(options.subnetId || this.subnetId, null, { unique: 1 });
}
if (!lib.isEmpty(network)) {
req.networkConfiguration = { awsvpcConfiguration: network };
}
var overrides = {};
if (options.cpu) {
overrides.cpu = String(options.cpu);
}
if (options.memory) {
overrides.memory = String(options.memory);
}
if (options.disk) {
overrides.ephemeralStorage = { sizeInGiB: options.disk };
}
if (options.role) {
overrides.taskRoleArn = options.role;
}
if (options.execRole) {
overrides.executionRoleArn = options.execRole;
}
if (options.container) {
var co = { name: options.container };
overrides.containerOverrides = [co];
if (options.env) {
co.environment = [];
for (const p in options.env) {
co.environment.push({ name: p, value: options.env[p] });
}
}
if (lib.isArray(options.files)) {
co.environmentFiles = options.files.map((x) => ({ type: "s3", value: x }));
}
if (options.cpu) {
co.cpu = lib.toNumber(options.cpu);
}
if (options.memory) {
co.memory = lib.toNumber(options.memory);
}
}
if (!lib.isEmpty(overrides)) {
req.overrides = overrides;
}
logger.debug('eccRunTask:', this.name, req, "OPTS:", options);
this.queryECS("RunTask", req, options, callback);
}
/**
* @memberof module:aws
* @method ecsTaskProtection
*/
aws.ecsTaskProtection = function(options, callback)
{
if (typeof options == "function") callback = options, options = null;
if (!process.env.ECS_AGENT_URI) return lib.tryCall(callback);
var url = process.env.ECS_AGENT_URI + "/task-protection/v1/state";
var postdata = options?.minutes > 0 ? { ProtectionEnabled: true, ExpiresInMinutes: options.minutes } :
options?.minutues <= 0 ? { ProtectionEnabled: false } : undefined;
aws.fetch(url, { method: postdata ? "PUT" : "GET", obj: 1, postdata }, callback);
}