import { module } from 'angular' ; import type { IVpc } from '@spinnaker/core' ; import type { IAmazonServerGroupCommand , IAmazonServerGroupDeployConfiguration } from './configure' ; import type { IAmazonServerGroup , IAmazonServerGroupView , IScalingAdjustmentView , IScalingPolicy , IScalingPolicyAlarmView , IScalingPolicyView , IStepAdjustmentView , ITargetTrackingPolicy , } from '../domain' ; import { VpcReader } from '../vpc/VpcReader' ; export class AwsServerGroupTransformer { private addComparator ( alarm ) { if ( ! alarm . comparisonOperator ) { return ; } switch ( alarm . comparisonOperator ) { case 'LessThanThreshold' : alarm . comparator = '&lt;' ; break ; case 'GreaterThanThreshold' : alarm . comparator = '&gt;' ; break ; case 'LessThanOrEqualToThreshold' : alarm . comparator = '&le;' ; break ; case 'GreaterThanOrEqualToThreshold' : alarm . comparator = '&ge;' ; break ; } } private addAdjustmentAttributes ( policyOrStepAdjustment ) { policyOrStepAdjustment . operator = policyOrStepAdjustment . scalingAdjustment < 0 ? 'decrease' : 'increase' ; policyOrStepAdjustment . absAdjustment = Math . abs ( policyOrStepAdjustment . scalingAdjustment ) ; } public transformScalingPolicy ( policy ) { const view = { ... policy } as IScalingPolicyView ; const upperBoundSorter = ( a , b ) => b . metricIntervalUpperBound - a . metricIntervalUpperBound ; const lowerBoundSorter = ( a , b ) => a . metricIntervalLowerBound - b . metricIntervalLowerBound ; view . alarms = policy . alarms || [ ] ; view . alarms . forEach ( ( alarm ) => this . addComparator ( alarm ) ) ; this . addAdjustmentAttributes ( view ) ; if ( view . stepAdjustments && view . stepAdjustments . length ) { view . stepAdjustments . forEach ( ( sa ) => this . addAdjustmentAttributes ( sa ) ) ; const sorter = policy . stepAdjustments . every ( ( a ) => a . metricIntervalUpperBound !== undefined ) ? upperBoundSorter : lowerBoundSorter ; view . stepAdjustments . sort ( ( a , b ) => sorter ( a , b ) ) ; } return view ; } public normalizeServerGroupDetails ( serverGroup ) { const view = { ... serverGroup } as IAmazonServerGroupView ; if ( serverGroup . scalingPolicies ) { view . scalingPolicies = serverGroup . scalingPolicies . map ( ( policy ) => this . transformScalingPolicy ( policy ) ) ; } return view ; } public normalizeServerGroup ( serverGroup ) { serverGroup . instances . forEach ( ( instance ) => { instance . vpcId = serverGroup . vpcId ; } ) ; return VpcReader . listVpcs ( ) . then ( ( vpc ) => this . addVpcNameToServerGroup ( serverGroup ) ( vpc ) ) ; } private addVpcNameToServerGroup ( serverGroup ) { return ( vpcs ) => { const match = vpcs . find ( ( test ) => test . id === serverGroup . vpcId ) ; serverGroup . vpcName = match ? match . name : '' ; return serverGroup ; } ; } public convertServerGroupCommandToDeployConfiguration ( base ) { const deployConfig = ( { ... base } as any ) as IAmazonServerGroupDeployConfiguration ; deployConfig . cloudProvider = 'aws' ; deployConfig . availabilityZones = { [ deployConfig . region ] : base . availabilityZones } ; deployConfig . loadBalancers = ( base . loadBalancers || [ ] ) . concat ( base . vpcLoadBalancers || [ ] ) ; deployConfig . targetGroups = base . targetGroups || [ ] ; deployConfig . account = deployConfig . credentials ; deployConfig . subnetType = deployConfig . subnetType || '' ; if ( base . viewState . mode !== 'clone' ) { delete deployConfig . source ; } if ( ! deployConfig . ramdiskId ) { delete deployConfig . ramdiskId ; } const deleteFields = [ 'region' , 'viewState' , 'backingData' , 'selectedProvider' , 'instanceProfile' , 'vpcId' ] ; deleteFields . forEach ( ( key ) => { delete deployConfig [ key ] ; } ) ; return deployConfig ; } public constructNewStepScalingPolicyTemplate ( serverGroup ) { return { alarms : [ { namespace : 'AWS/EC2' , metricName : 'CPUUtilization' , threshold : 50 , statistic : 'Average' , comparisonOperator : 'GreaterThanThreshold' , evaluationPeriods : 1 , dimensions : [ { name : 'AutoScalingGroupName' , value : serverGroup . name } ] , period : 60 , } , ] , adjustmentType : 'ChangeInCapacity' , stepAdjustments : [ { scalingAdjustment : 1 , metricIntervalLowerBound : 0 , } , ] , estimatedInstanceWarmup : 600 , } ; } public constructNewTargetTrackingPolicyTemplate ( ) { return { alarms : [ ] , estimatedInstanceWarmup : 300 , targetTrackingConfiguration : { targetValue : null , predefinedMetricSpecification : { predefinedMetricType : 'ASGAverageCPUUtilization' , } , } , } ; } } export const AWS_SERVER_GROUP_TRANSFORMER = 'spinnaker.amazon.serverGroup.transformer' ; module ( AWS_SERVER_GROUP_TRANSFORMER , [ ] ) . service ( 'awsServerGroupTransformer' , AwsServerGroupTransformer ) ;