serverless-tasks-handel-extension
Advanced tools
Comparing version 0.2.2 to 0.2.3
@@ -10,6 +10,18 @@ /** | ||
ecs: { | ||
describeClusters: (params: AWS.ECS.DescribeClustersRequest) => Promise<import("aws-sdk/lib/request").PromiseResult<AWS.ECS.DescribeClustersResponse, AWS.AWSError>>; | ||
createCluster: (params: AWS.ECS.CreateClusterRequest) => Promise<import("aws-sdk/lib/request").PromiseResult<AWS.ECS.CreateClusterResponse, AWS.AWSError>>; | ||
describeClusters: (params: AWS.ECS.DescribeClustersRequest) => Promise<AWS.ECS.DescribeClustersResponse & { | ||
$response: AWS.Response<AWS.ECS.DescribeClustersResponse, AWS.AWSError>; | ||
}>; | ||
createCluster: (params: AWS.ECS.CreateClusterRequest) => Promise<AWS.ECS.CreateClusterResponse & { | ||
$response: AWS.Response<AWS.ECS.CreateClusterResponse, AWS.AWSError>; | ||
}>; | ||
}; | ||
lambda: { | ||
addPermission: (params: AWS.Lambda.AddPermissionRequest) => Promise<AWS.Lambda.AddPermissionResponse & { | ||
$response: AWS.Response<AWS.Lambda.AddPermissionResponse, AWS.AWSError>; | ||
}>; | ||
getPolicy: (params: AWS.Lambda.GetPolicyRequest) => Promise<AWS.Lambda.GetPolicyResponse & { | ||
$response: AWS.Response<AWS.Lambda.GetPolicyResponse, AWS.AWSError>; | ||
}>; | ||
}; | ||
}; | ||
export default awsWrapper; |
@@ -36,2 +36,12 @@ "use strict"; | ||
} | ||
}, | ||
lambda: { | ||
addPermission: (params) => { | ||
const lambda = new AWS.Lambda({ apiVersion: '2015-03-31' }); | ||
return lambda.addPermission(params).promise(); | ||
}, | ||
getPolicy: (params) => { | ||
const lambda = new AWS.Lambda({ apiVersion: '2015-03-31' }); | ||
return lambda.getPolicy(params).promise(); | ||
} | ||
} | ||
@@ -38,0 +48,0 @@ }; |
@@ -0,0 +0,0 @@ import { EnvironmentVariables, ServiceConfig } from 'handel-extension-api'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=config-types.js.map |
import * as AWS from 'aws-sdk'; | ||
export declare function getCluster(clusterName: string): Promise<AWS.ECS.Cluster | null>; | ||
export declare function createDefaultClusterIfNotExists(): Promise<AWS.ECS.Cluster | null>; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -9,0 +8,0 @@ }); |
import { ExtensionContext } from 'handel-extension-api'; | ||
export declare function loadHandelExtension(context: ExtensionContext): void; |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ import * as AWS from 'aws-sdk'; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -9,0 +8,0 @@ }); |
@@ -1,18 +0,20 @@ | ||
import { DeployOutputType, PreDeployContext, ServiceConfig, ServiceContext, ServiceDeployer, UnDeployContext, UnPreDeployContext } from 'handel-extension-api'; | ||
import { DeployOutputType, PreDeployContext, ProduceEventsContext, ServiceConfig, ServiceContext, ServiceDeployer, ServiceEventConsumer, ServiceEventType, UnDeployContext, UnPreDeployContext } from 'handel-extension-api'; | ||
import { DeployContext } from 'handel-extension-api'; | ||
import { ScheduledTasksServiceConfig } from './config-types'; | ||
export declare function addProducePermissions(ownServiceContext: ServiceContext<ScheduledTasksServiceConfig>, ownDeployContext: DeployContext, producerDeployContext: DeployContext): Promise<void>; | ||
export declare class ScheduledTasksService implements ServiceDeployer { | ||
readonly consumedDeployOutputTypes: DeployOutputType[]; | ||
readonly providedEventType: null; | ||
readonly producedDeployOutputTypes: never[]; | ||
readonly providedEventType: ServiceEventType; | ||
readonly producedDeployOutputTypes: DeployOutputType[]; | ||
readonly producedEventsSupportedTypes: never[]; | ||
readonly supportsTagging = true; | ||
readonly supportsTagging: boolean; | ||
check(serviceContext: ServiceContext<ScheduledTasksServiceConfig>, dependenciesServiceContexts: Array<ServiceContext<ServiceConfig>>): string[]; | ||
preDeploy(serviceContext: ServiceContext<ScheduledTasksServiceConfig>): Promise<PreDeployContext>; | ||
deploy(ownServiceContext: ServiceContext<ScheduledTasksServiceConfig>, ownPreDeployContext: PreDeployContext, dependenciesDeployContexts: DeployContext[]): Promise<DeployContext>; | ||
consumeEvents(ownServiceContext: ServiceContext<ScheduledTasksServiceConfig>, ownDeployContext: DeployContext, eventConsumerConfig: ServiceEventConsumer, producerServiceContext: ServiceContext<ServiceConfig>, producerDeployContext: DeployContext): Promise<ProduceEventsContext>; | ||
unDeploy(ownServiceContext: ServiceContext<ScheduledTasksServiceConfig>): Promise<UnDeployContext>; | ||
unPreDeploy(ownServiceContext: ServiceContext<ScheduledTasksServiceConfig>): Promise<UnPreDeployContext>; | ||
private uploadInvokerLambdaCode; | ||
private getCompiledTemplate; | ||
private getImageName; | ||
private uploadInvokerLambdaCode(serviceContext); | ||
private getCompiledTemplate(resourceName, serviceContext, preDeployContext, dependenciesDeployContexts, s3ArtifactInfo, tags); | ||
private getImageName(ownServiceContext); | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -15,3 +14,8 @@ }); | ||
const handel_extension_support_1 = require("handel-extension-support"); | ||
const uuid_1 = require("uuid"); | ||
const winston = require("winston"); | ||
const aws_wrapper_1 = require("./aws-wrapper"); | ||
const ecsCalls = require("./ecs-calls"); | ||
// @ts-ignore | ||
winston.level = process.env.LOG_LEVEL || 'debug'; | ||
const SERVICE_NAME = 'ServerlessTasks'; | ||
@@ -50,2 +54,86 @@ function getDeployContext(serviceContext, cfStack) { | ||
} | ||
function statementIsSame(functionName, principal, sourceArn, statement) { | ||
if (statement.Principal.Service !== principal) { | ||
return false; | ||
} | ||
if (sourceArn && (!statement.Condition || !statement.Condition.ArnLike || statement.Condition.ArnLike['AWS:SourceArn'] !== sourceArn)) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
function getLambdaPermission(functionName, principal, sourceArn) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const getPolicyParams = { | ||
FunctionName: functionName | ||
}; | ||
// tslint:disable-next-line:no-console | ||
console.log(`Attempting to find permissions for ${principal} in function ${functionName}`); | ||
try { | ||
const getPolicyResponse = yield aws_wrapper_1.default.lambda.getPolicy(getPolicyParams); | ||
const policy = JSON.parse(getPolicyResponse.Policy); | ||
for (const statement of policy.Statement) { | ||
if (statementIsSame(functionName, principal, sourceArn, statement)) { | ||
// tslint:disable-next-line:no-console | ||
console.log(`Found permission ${principal} in function ${functionName}`); | ||
return statement; | ||
} | ||
} | ||
// tslint:disable-next-line:no-console | ||
console.log(`Permission ${sourceArn} in function ${functionName} does not exist`); | ||
return null; | ||
} | ||
catch (err) { | ||
if (err.code === 'ResourceNotFoundException') { | ||
// tslint:disable-next-line:no-console | ||
console.log(`Permission ${sourceArn} in function ${functionName} does not exist`); | ||
return null; | ||
} | ||
throw err; // Throw error on any other kind of error | ||
} | ||
}); | ||
} | ||
function addLambdaPermission(functionName, principal, sourceArn) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const addPermissionParams = { | ||
Action: 'lambda:InvokeFunction', | ||
FunctionName: functionName, | ||
Principal: principal, | ||
SourceArn: sourceArn, | ||
StatementId: `${uuid_1.v4()}` | ||
}; | ||
// tslint:disable-next-line:no-console | ||
console.log(`Adding Lambda permission to ${functionName}`); | ||
const response = yield aws_wrapper_1.default.lambda.addPermission(addPermissionParams); | ||
// tslint:disable-next-line:no-console | ||
console.log(`Added Lambda permission to ${functionName}`); | ||
return getLambdaPermission(functionName, principal, sourceArn); | ||
}); | ||
} | ||
function addLambdaPermissionIfNotExists(functionName, principal, sourceArn) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const permission = yield getLambdaPermission(functionName, principal, sourceArn); | ||
if (!permission) { | ||
return addLambdaPermission(functionName, principal, sourceArn); | ||
} | ||
else { | ||
return permission; | ||
} | ||
}); | ||
} | ||
function addProducePermissions(ownServiceContext, ownDeployContext, producerDeployContext) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!ownDeployContext.eventOutputs || !producerDeployContext.eventOutputs) { | ||
throw new Error(`Both the consumer and producer must return event outputs from their deploy`); | ||
} | ||
const functionName = ownDeployContext.eventOutputs.resourceName; | ||
if (!functionName) { | ||
throw new Error(`Expected to get function name for event binding`); | ||
} | ||
const principal = producerDeployContext.eventOutputs.resourcePrincipal; | ||
const sourceArn = producerDeployContext.eventOutputs.resourceArn; | ||
// Add Lambda Permission If Not Exists | ||
yield addLambdaPermissionIfNotExists(functionName, principal, sourceArn); | ||
}); | ||
} | ||
exports.addProducePermissions = addProducePermissions; | ||
class ScheduledTasksService { | ||
@@ -58,4 +146,6 @@ constructor() { | ||
]; | ||
this.providedEventType = null; | ||
this.producedDeployOutputTypes = []; | ||
this.providedEventType = handel_extension_api_1.ServiceEventType.Lambda; | ||
this.producedDeployOutputTypes = [ | ||
handel_extension_api_1.DeployOutputType.Policies | ||
]; | ||
this.producedEventsSupportedTypes = []; | ||
@@ -92,2 +182,15 @@ this.supportsTagging = true; | ||
} | ||
consumeEvents(ownServiceContext, ownDeployContext, eventConsumerConfig, producerServiceContext, producerDeployContext) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// tslint:disable-next-line:no-console | ||
console.log(`${SERVICE_NAME} - Consuming events from service '${producerServiceContext.serviceName}' for service '${ownServiceContext.serviceName}'`); | ||
if (!producerDeployContext.eventOutputs) { | ||
throw new Error(`${SERVICE_NAME} - The producer must return event outputs from their deploy`); | ||
} | ||
yield addProducePermissions(ownServiceContext, ownDeployContext, producerDeployContext); | ||
// tslint:disable-next-line:no-console | ||
console.log(`${SERVICE_NAME} - Allowed consuming events from ${producerServiceContext.serviceName} for ${ownServiceContext.serviceName}`); | ||
return new handel_extension_api_1.ConsumeEventsContext(ownServiceContext, producerServiceContext); | ||
}); | ||
} | ||
unDeploy(ownServiceContext) { | ||
@@ -94,0 +197,0 @@ return handel_extension_support_1.deletePhases.unDeployService(ownServiceContext, SERVICE_NAME); |
{ | ||
"name": "serverless-tasks-handel-extension", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "Handel Extension that provides serverless scheduled tasks using ECS Fargate", | ||
@@ -22,4 +22,3 @@ "main": "dist/extension.js", | ||
"handel-extension-support": "^0.31.1", | ||
"uuid": "^7.0.2", | ||
"winston": "^2.3.1" | ||
"uuid": "^7.0.2" | ||
}, | ||
@@ -32,3 +31,2 @@ "devDependencies": { | ||
"@types/uuid": "^7.0.0", | ||
"@types/winston": "2.3.1", | ||
"chai": "^4.1.2", | ||
@@ -35,0 +33,0 @@ "cpy-cli": "^2.0.0", |
@@ -43,3 +43,2 @@ /* | ||
import { v4 as uuid } from 'uuid'; | ||
import * as winston from 'winston'; | ||
import awsWrapper from './aws-wrapper'; | ||
@@ -49,5 +48,2 @@ import { ScheduledTasksServiceConfig } from './config-types'; | ||
// @ts-ignore | ||
winston.level = process.env.LOG_LEVEL || 'debug'; | ||
const SERVICE_NAME = 'ServerlessTasks'; | ||
@@ -54,0 +50,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
95964
4
14
39
1208
6
- Removedwinston@^2.3.1
- Removedwinston@2.4.7(transitive)