All files / src/resolvers/hosts Ec2HostResolver.ts

100% Statements 30/30
100% Branches 7/7
100% Functions 4/4
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58  4x       4x 4x 10x         10x 10x       9x 7x 7x 7x 7x 7x   2x         7x 7x   7x   7x 7x 7x 6x 6x         7x 7x 7x   5x 5x   2x 2x     7x 7x    
import { ConfigServiceClient } from "@aws-sdk/client-config-service";
import { ARN, parse } from "@aws-sdk/util-arn-parser";
import { FlowHost, FlowRuleGroup,  ResolvedFlowHost } from "../../FlowDefinitions";
import { LoggerFactory } from "../../logger-factory";
import { Logger } from "../../logger-type";
import { CloudResourceHostResolver } from "./CloudResourceHostResolver";
export class Ec2HostResolver extends CloudResourceHostResolver {
    SUPPORTED_EC2_RESOURCE_REGX = /(security-group|instance)\/(.+)/
    logger: Logger;
    constructor(loggerFactory: LoggerFactory,
        configServiceClient: ConfigServiceClient,
        defaultAggregatorName?: string) {
        super(configServiceClient, defaultAggregatorName);
        this.logger = loggerFactory.getLogger('Ec2HostResolver');
    }
 
    canResolve(host: FlowHost): boolean {
        if (host.type === 'Arn') {
            const arn = parse(host.value);
            const match = arn.resource.match(this.SUPPORTED_EC2_RESOURCE_REGX);
            const canResolve = arn.service === 'ec2' && match != null && match[1] != null;
            this.logger.info(`arn is resolvable => ${canResolve}`, arn);
            return canResolve;
        } else {
            return false;
        }
    }
 
    async resolve(hsot: FlowHost, ruleGroup?: FlowRuleGroup): Promise<ResolvedFlowHost> {
        const arn = parse(hsot.value);
        this.logger.info('parsed arn', arn);
 
        const match = arn.resource.match(this.SUPPORTED_EC2_RESOURCE_REGX);
 
        const configAdvancedQueryString = this.createQueryString(match!, arn);
        this.logger.info(`configAdvancedQueryString ${configAdvancedQueryString}`);
        const data = await this.queryAwsConfig(ruleGroup, configAdvancedQueryString);
        this.logger.info('parsed data', data);
        return this.parseResult(this.logger, data, hsot);
    }
 
    private createQueryString(match: RegExpMatchArray, arn: ARN) {
        let configAdvancedQueryString;
        const resourceId = match![2];
        this.logger.info(`query for type ${match![1]}`);
        switch (match![1]) {
            case 'instance':
                configAdvancedQueryString = `SELECT configuration.privateIpAddress WHERE resourceType='AWS::EC2::Instance' AND configuration.instanceId = '${resourceId}' and accountId=${arn.accountId}`;
                break;
            case 'security-group':
                configAdvancedQueryString = `SELECT configuration.privateIpAddress WHERE resourceType='AWS::EC2::Instance' AND  relationships.resourceId = '${resourceId}' and accountId=${arn.accountId}`;
                break;
        }
 
        this.logger.info(`configAdvancedQueryString ${configAdvancedQueryString}`);
        return configAdvancedQueryString;
    }
}