From 91cd5c997a0a9781cd488e0d67315eda2fb94991 Mon Sep 17 00:00:00 2001 From: e0d Date: Sat, 15 Feb 2014 12:05:52 -0500 Subject: [PATCH] initial working version Fixing missing imports filtering tags. fixing npe. code narc test for tag copy --- .../com/netflix/asgard/ClusterController.groovy | 12 +++++++++++- .../netflix/asgard/push/GroupCreateOperation.groovy | 4 +++- .../netflix/asgard/push/GroupCreateOptions.groovy | 3 +++ .../com/netflix/asgard/ClusterControllerSpec.groovy | 11 ++++++++++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/grails-app/controllers/com/netflix/asgard/ClusterController.groovy b/grails-app/controllers/com/netflix/asgard/ClusterController.groovy index ab217a29..b4f32ee0 100644 --- a/grails-app/controllers/com/netflix/asgard/ClusterController.groovy +++ b/grails-app/controllers/com/netflix/asgard/ClusterController.groovy @@ -18,6 +18,7 @@ package com.netflix.asgard import com.amazonaws.services.autoscaling.model.AutoScalingGroup import com.amazonaws.services.autoscaling.model.LaunchConfiguration import com.amazonaws.services.autoscaling.model.ScheduledUpdateGroupAction +import com.amazonaws.services.autoscaling.model.TagDescription import com.amazonaws.services.ec2.model.AvailabilityZone import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription import com.amazonaws.services.simpleworkflow.flow.ManualActivityCompletionClient @@ -43,6 +44,7 @@ import com.netflix.asgard.push.GroupDeleteOperation import com.netflix.asgard.push.GroupResizeOperation import com.netflix.asgard.push.InitialTraffic import com.netflix.grails.contextParam.ContextParam + import grails.converters.JSON import grails.converters.XML @@ -423,6 +425,8 @@ ${lastGroup.loadBalancerNames}""" List newScheduledActions = awsAutoScalingService.copyScheduledActionsForNewAsg( userContext, nextGroupName, lastScheduledActions) + List tags = getCopyForwardTags(lastGroup) + Integer lastGracePeriod = lastGroup.healthCheckGracePeriod String vpcZoneIdentifier = subnets.constructNewVpcZoneIdentifierForPurposeAndZones(subnetPurpose, selectedZones) @@ -474,7 +478,8 @@ Group: ${loadBalancerNames}""" scheduledActions: newScheduledActions, vpcZoneIdentifier: vpcZoneIdentifier, spotPrice: spotPrice, - ebsOptimized: ebsOptimized + ebsOptimized: ebsOptimized, + tags: tags ) def operation = pushService.startGroupCreate(options) flash.message = "${operation.task.name} has been started." @@ -482,6 +487,11 @@ Group: ${loadBalancerNames}""" } } + private List getCopyForwardTags(AutoScalingGroupData asg) { + //Tag keys starting with the String aws are reserved. + List copyForwardTags = asg?.tags.findAll{ ! it?.key.startsWith("aws") } + } + private int convertToIntOrUseDefault(String value, Integer defaultValue) { value?.toInteger() ?: defaultValue } diff --git a/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy b/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy index 748423ac..9f83cc02 100644 --- a/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy +++ b/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy @@ -75,7 +75,9 @@ class GroupCreateOperation extends AbstractPushOperation { withDefaultCooldown(options.defaultCooldown).withHealthCheckType(options.healthCheckType). withHealthCheckGracePeriod(options.healthCheckGracePeriod). withTerminationPolicies(options.terminationPolicies). - withVPCZoneIdentifier(options.vpcZoneIdentifier) + withVPCZoneIdentifier(options.vpcZoneIdentifier). + withTags(options.tags) + LaunchConfiguration launchConfigTemplate = new LaunchConfiguration().withImageId(options.common.imageId). withKernelId(options.kernelId).withInstanceType(options.common.instanceType). withKeyName(options.keyName).withRamdiskId(options.ramdiskId). diff --git a/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy b/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy index 1ba5fa21..3e092a69 100644 --- a/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy +++ b/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy @@ -16,7 +16,9 @@ package com.netflix.asgard.push import com.amazonaws.services.autoscaling.model.ScheduledUpdateGroupAction +import com.amazonaws.services.autoscaling.model.TagDescription import com.netflix.asgard.model.ScalingPolicyData + import groovy.transform.Immutable @Immutable final class GroupCreateOptions { @@ -35,6 +37,7 @@ import groovy.transform.Immutable boolean zoneRebalancingSuspended Collection scalingPolicies Collection scheduledActions + Collection tags String spotPrice boolean ebsOptimized diff --git a/test/unit/com/netflix/asgard/ClusterControllerSpec.groovy b/test/unit/com/netflix/asgard/ClusterControllerSpec.groovy index c8934ba0..38b9d313 100644 --- a/test/unit/com/netflix/asgard/ClusterControllerSpec.groovy +++ b/test/unit/com/netflix/asgard/ClusterControllerSpec.groovy @@ -18,6 +18,7 @@ package com.netflix.asgard import com.amazonaws.services.autoscaling.model.AutoScalingGroup import com.amazonaws.services.autoscaling.model.Instance import com.amazonaws.services.autoscaling.model.LaunchConfiguration +import com.amazonaws.services.autoscaling.model.TagDescription import com.netflix.asgard.model.AutoScalingGroupData import com.netflix.asgard.model.AutoScalingGroupHealthCheckType import com.netflix.asgard.model.AutoScalingGroupMixin @@ -28,6 +29,7 @@ import com.netflix.asgard.model.Subnets import com.netflix.asgard.push.Cluster import com.netflix.asgard.push.GroupCreateOperation import com.netflix.asgard.push.GroupCreateOptions + import grails.test.mixin.TestFor import spock.lang.Specification import spock.lang.Unroll @@ -46,12 +48,18 @@ class ClusterControllerSpec extends Specification { subnet('subnet-3', 'us-east-1e', 'internal'), subnet('subnet-4', 'us-east-1e', 'external'), ]) + + // Two tags are defined here to ensure that tags beginning with aws are not copied forward as + // they are reserved for AWS internal use, e.g., aws:autoscaling:groupName + final allowedTag = new TagDescription(propagateAtLaunch: true, key: "deployment", value: "test") + final forbiddenTag = new TagDescription(propagateAtLaunch: true, key: "aws:test", value: "aws") + final AutoScalingGroup asg = new AutoScalingGroup(autoScalingGroupName: 'helloworld-example-v015', minSize: 3, desiredCapacity: 5, maxSize: 7, healthCheckGracePeriod: 42, defaultCooldown: 360, launchConfigurationName: 'helloworld-lc', healthCheckType: AutoScalingGroupHealthCheckType.EC2, instances: [new Instance(instanceId: 'i-6ef9f30e'), new Instance(instanceId: 'i-95fe1df6')], availabilityZones: ['us-east-1c'], loadBalancerNames: ['hello-elb'], terminationPolicies: ['hello-tp'], - vPCZoneIdentifier: 'subnet-1') + vPCZoneIdentifier: 'subnet-1', tags: [allowedTag, forbiddenTag]) final LaunchConfiguration launchConfiguration = new LaunchConfiguration(imageId: 'lastImageId', instanceType: 'lastInstanceType', keyName: 'lastKeyName', securityGroups: ['sg-123', 'sg-456'], iamInstanceProfile: 'lastIamProfile', spotPrice: '1.23') @@ -166,6 +174,7 @@ class ClusterControllerSpec extends Specification { assert vpcZoneIdentifier == 'subnet-1' assert iamInstanceProfile == 'lastIamProfile' assert spotPrice == '1.23' + assert tags == [allowedTag] } true }) >> { args ->