import { CloudFormation } from "aws-sdk" ; import { CloudFormationEvent , CustomTag , StackJanitorStatus } from "stackjanitor" ; import { logger } from "../logger" ; import { Stack , Tag } from "aws-sdk/clients/cloudformation" ; import { generateDeleteItem , handleDataItem , RequestType } from "./monitorCloudFormationStack" ; import { StackStatus , TagName } from "../tag/TagStatus" ; import { dataModel } from "../data/DynamoDataModel" ; const cloudFormation = new CloudFormation ( ) ; export const getTagsFromStacks = ( stacks ) : Tag [ ] => stacks . filter ( stackInfo => Array . isArray ( stackInfo . Tags ) ) . map ( stackInfo => stackInfo . Tags ! ) . reduce ( ( currentTag , accumulatedTags ) => accumulatedTags . concat ( currentTag ) ) ; export const findTag = ( tags ) => tags . find ( t => t . key === TagName ) ; export const getStackJanitorStatus = ( tags ) : StackStatus => { const tag = findTag ( tags ) ; if ( tag && tag . value === StackStatus . Enabled ) { return StackStatus . Enabled ; } return StackStatus . Disabled ; } ; export const convertTags = ( tags ) : CustomTag [ ] => tags . map ( tag => ( { key : tag . Key , value : tag . Value } ) ) ; export const logCloudFormationStack = async ( event , cloudFormation ) => { let stackStatus = StackStatus . Disabled ; const eventName = event . detail . eventName ; if ( eventName === RequestType . Create ) { const tags = event . detail . requestParameters . tags ; stackStatus = getStackJanitorStatus ( tags ) ; } else { try { const { Stacks } = await cloudFormation . describeStacks ( { StackName : event . detail . requestParameters . stackName } ) . promise ( ) ; if ( Stacks ) { const tags = getTagsFromStacks ( Stacks ) ; const customTags = convertTags ( tags ) ; event . detail . requestParameters . tags = customTags ; stackStatus = getStackJanitorStatus ( customTags ) ; } } catch ( e ) { logger . error ( { event , stack : e . stack } , e . message ) ; } if ( eventName === RequestType . Update && stackStatus !== StackStatus . Enabled ) { const item = generateDeleteItem ( event ) ; await handleDataItem ( item , dataModel . destroy ) ; } } return { event , results : { stackjanitor : stackStatus } } ; } ; export const index = async ( event ) : Promise < StackJanitorStatus > => { return await logCloudFormationStack ( event , cloudFormation ) ; } ;