From dfd745bd82f1253b1bfe279b54404a6e2aecafb1 Mon Sep 17 00:00:00 2001 From: Peter Idah Date: Tue, 21 Apr 2015 18:01:32 +0100 Subject: [PATCH 1/2] DNSNAME instead of CanonicalHostedZoneName: When *internal* is specified for the ELB scheme, the load balancer doesn't have a **CanonicalHostedZoneName** value. **DNSName** value exists for both *internal* and *internet-facing* ELB schemes. --- bootstrap_cfn/config.py | 2 +- tests/sample-project.yaml | 2 +- tests/tests.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bootstrap_cfn/config.py b/bootstrap_cfn/config.py index 718ffdc..5c108d7 100644 --- a/bootstrap_cfn/config.py +++ b/bootstrap_cfn/config.py @@ -220,7 +220,7 @@ def elb(self): 'CanonicalHostedZoneNameID'] target_dns = [ 'ELB%s' % safe_name, - 'CanonicalHostedZoneName'] + 'DNSName'] template['DNSRecord']['Properties']['RecordSets'][0][ 'AliasTarget']['HostedZoneId']['Fn::GetAtt'] = target_zone template['DNSRecord']['Properties']['RecordSets'][0][ diff --git a/tests/sample-project.yaml b/tests/sample-project.yaml index 21d87e6..9e88cd5 100644 --- a/tests/sample-project.yaml +++ b/tests/sample-project.yaml @@ -45,7 +45,7 @@ dev: Protocol: TCP - name: test-dev-internal hosted_zone: kyrtest.pf.dsd.io. - scheme: internet-facing + scheme: internal listeners: - LoadBalancerPort: 80 InstancePort: 80 diff --git a/tests/tests.py b/tests/tests.py index a752a14..51f1092 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -205,7 +205,7 @@ def test_elb(self): u'HostedZoneName': 'kyrtest.pf.dsd.io.', u'RecordSets': [ {u'AliasTarget': { - u'DNSName': {u'Fn::GetAtt': ['ELBtestdevexternal', 'CanonicalHostedZoneName']}, + u'DNSName': {u'Fn::GetAtt': ['ELBtestdevexternal', 'DNSName']}, u'HostedZoneId': {u'Fn::GetAtt': ['ELBtestdevexternal', 'CanonicalHostedZoneNameID']}}, u'Name': 'test-dev-external.kyrtest.pf.dsd.io.', u'Type': u'A'} @@ -221,7 +221,7 @@ def test_elb(self): ], u'LoadBalancerName': 'ELB-test-dev-internal', u'SecurityGroups': [{u'Ref': u'DefaultSGtestdevinternal'}], - u'Scheme': 'internet-facing', + u'Scheme': 'internal', u'Subnets': [ {u'Ref': u'SubnetA'}, {u'Ref': u'SubnetB'}, @@ -235,7 +235,7 @@ def test_elb(self): u'HostedZoneName': 'kyrtest.pf.dsd.io.', u'RecordSets': [ {u'AliasTarget': { - u'DNSName': {u'Fn::GetAtt': ['ELBtestdevinternal', 'CanonicalHostedZoneName']}, + u'DNSName': {u'Fn::GetAtt': ['ELBtestdevinternal', 'DNSName']}, u'HostedZoneId': {u'Fn::GetAtt': ['ELBtestdevinternal', 'CanonicalHostedZoneNameID']}}, u'Name': 'test-dev-internal.kyrtest.pf.dsd.io.', u'Type': u'A'} @@ -449,7 +449,7 @@ def test_elb_with_ssl(self): {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', 'HostedZoneName': 'kyrtest.foo.bar.', 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'CanonicalHostedZoneName']}, + 'DNSName']}, 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', 'CanonicalHostedZoneNameID']}}, 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', @@ -499,7 +499,7 @@ def test_elb_with_reserved_chars(self): {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', 'HostedZoneName': 'kyrtest.foo.bar.', 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'CanonicalHostedZoneName']}, + 'DNSName']}, 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', 'CanonicalHostedZoneNameID']}}, 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', From 45a51438ce600171d4bb0318b57bab06784dc1ef Mon Sep 17 00:00:00 2001 From: Peter Idah Date: Fri, 24 Apr 2015 14:55:00 +0100 Subject: [PATCH 2/2] pep8 fixes --- bootstrap_cfn/config.py | 78 +++++++--- tests/tests.py | 330 ++++++++++++++++++++-------------------- 2 files changed, 224 insertions(+), 184 deletions(-) diff --git a/bootstrap_cfn/config.py b/bootstrap_cfn/config.py index 5c108d7..4a4e24e 100644 --- a/bootstrap_cfn/config.py +++ b/bootstrap_cfn/config.py @@ -8,6 +8,7 @@ from copy import deepcopy + class ProjectConfig: config = None @@ -69,13 +70,20 @@ def process(self): for k, v in elb_sgs.items(): data[k] = v - template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/base.json')) + template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/base.json')) if 'vpc' in self.data: template['Mappings']['SubnetConfig']['VPC'] = self.data['vpc'] template['Resources'] = data template['Outputs'] = {} for t in output_templates: - template['Outputs'].update(json.loads(pkgutil.get_data('bootstrap_cfn', t))) + template['Outputs'].update( + json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + t))) if 'includes' in self.data: for inc_path in self.data['includes']: inc = json.load(open(inc_path)) @@ -98,7 +106,10 @@ def s3(self): } # LOAD STACK TEMPLATE - template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/s3.json')) + template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/s3.json')) # TEST FOR REQUIRED FIELDS AND EXIT IF MISSING ANY present_keys = self.data['s3'].keys() @@ -111,11 +122,21 @@ def s3(self): if 'policy' in present_keys: policy = json.loads(open(self.data['s3']['policy']).read()) else: - arn = 'arn:aws:s3:::%s/*' % self.data['s3']['static-bucket-name'] - policy = {'Action': ['s3:Get*', 's3:Put*', 's3:List*'], 'Resource': arn, 'Effect': 'Allow', 'Principal' : {'AWS' : '*'}} - - template['StaticBucket']['Properties']['BucketName'] = self.data['s3']['static-bucket-name'] - template['StaticBucketPolicy']['Properties']['PolicyDocument']['Statement'][0] = policy + arn = 'arn:aws:s3:::%s/*' % self.data['s3']['static-bucket-name'] + policy = { + 'Action': [ + 's3:Get*', + 's3:Put*', + 's3:List*'], + 'Resource': arn, + 'Effect': 'Allow', + 'Principal': { + 'AWS': '*'}} + + template['StaticBucket']['Properties'][ + 'BucketName'] = self.data['s3']['static-bucket-name'] + template['StaticBucketPolicy']['Properties'][ + 'PolicyDocument']['Statement'][0] = policy return template @@ -139,7 +160,10 @@ def rds(self): } # LOAD STACK TEMPLATE - template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/rds.json')) + template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/rds.json')) # TEST FOR REQUIRED FIELDS AND EXIT IF MISSING ANY for i in required_fields.keys(): @@ -173,36 +197,46 @@ def elb(self): sys.exit(1) # LOAD STACK TEMPLATE - template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/elb.json')) + template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/elb.json')) # LOAD SSL TEMPLATE - ssl_template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/elb_ssl.json')) + ssl_template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/elb_ssl.json')) for listener in elb['listeners']: if listener['Protocol'] == 'HTTPS': try: cert_name = elb['certificate_name'] except KeyError: - raise errors.CfnConfigError("HTTPS listener but no certificate_name specified") + raise errors.CfnConfigError( + "HTTPS listener but no certificate_name specified") try: self.ssl()[cert_name]['cert'] self.ssl()[cert_name]['key'] except KeyError: - raise errors.CfnConfigError("Couldn't find ssl cert {0} in config file".format(cert_name)) - ssl_template["SSLCertificateId"]['Fn::Join'][1].append("{0}-{1}".format(cert_name, self.stack_name)) + raise errors.CfnConfigError( + "Couldn't find ssl cert {0} in config file".format(cert_name)) + ssl_template["SSLCertificateId"]['Fn::Join'][1].append( + "{0}-{1}".format(cert_name, self.stack_name)) listener.update(ssl_template) - elb_sg = template.pop('DefaultELBSecurityGroup') if 'security_groups' in elb: for sg_name, sg in elb['security_groups'].items(): new_sg = deepcopy(elb_sg) new_sg['Properties']['SecurityGroupIngress'] = sg elb_sgs[sg_name] = new_sg - template['ElasticLoadBalancer']['Properties']['SecurityGroups'] = [{'Ref': k} for k in elb['security_groups'].keys()] + template['ElasticLoadBalancer']['Properties']['SecurityGroups'] = [ + {'Ref': k} for k in elb['security_groups'].keys()] else: elb_sgs['DefaultSG' + safe_name] = elb_sg - template['ElasticLoadBalancer']['Properties']['SecurityGroups'] = [{'Ref': 'DefaultSG' + safe_name }] + template['ElasticLoadBalancer']['Properties'][ + 'SecurityGroups'] = [{'Ref': 'DefaultSG' + safe_name}] # CONFIGURE THE LISTENERS, ELB NAME AND ROUTE53 RECORDS template['ElasticLoadBalancer']['Properties'][ @@ -235,7 +269,10 @@ def elb(self): def ec2(self): # LOAD STACK TEMPLATE - template = json.loads(pkgutil.get_data('bootstrap_cfn', 'stacks/ec2.json')) + template = json.loads( + pkgutil.get_data( + 'bootstrap_cfn', + 'stacks/ec2.json')) # SET SECURITY GROUPS, DEFAULT KEY AND INSTANCE TYPE sg_t = template.pop('BaseHostSG') @@ -244,7 +281,8 @@ def ec2(self): new_sg['Properties']['SecurityGroupIngress'] = sg template[sg_name] = new_sg - template['BaseHostLaunchConfig']['Properties']['SecurityGroups'] = [{'Ref': k} for k in self.data['ec2']['security_groups'].keys()] + template['BaseHostLaunchConfig']['Properties']['SecurityGroups'] = [ + {'Ref': k} for k in self.data['ec2']['security_groups'].keys()] template['BaseHostLaunchConfig']['Properties'][ 'KeyName'] = self.data['ec2']['parameters']['KeyName'] template['BaseHostLaunchConfig']['Properties'][ @@ -258,7 +296,7 @@ def ec2(self): {'DeviceName': i['DeviceName'], 'Ebs': {'VolumeSize': i['VolumeSize']}}) except KeyError: devices.append( - {'DeviceName': '/dev/sda1', 'Ebs': {'VolumeSize': 20 }}) + {'DeviceName': '/dev/sda1', 'Ebs': {'VolumeSize': 20}}) template['BaseHostLaunchConfig']['Properties'][ 'BlockDeviceMappings'] = devices diff --git a/tests/tests.py b/tests/tests.py index 51f1092..ef9a0ee 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -20,7 +20,7 @@ def test_project_config(self): self.assertEquals( sorted( config.config.keys()), [ - 'ec2', 'elb', 'rds', 's3','ssl']) + 'ec2', 'elb', 'rds', 's3', 'ssl']) def test_project_config_merge_password(self): ''' @@ -103,7 +103,11 @@ def test_s3(self): ProjectConfig( 'tests/sample-project.yaml', 'dev').config, 'my-stack-name') - config = ConfigParser(ProjectConfig('tests/sample-project.yaml', 'dev').config, 'my-stack-name') + config = ConfigParser( + ProjectConfig( + 'tests/sample-project.yaml', + 'dev').config, + 'my-stack-name') self.assertEquals(known, config.s3()) def test_custom_s3_policy(self): @@ -137,43 +141,42 @@ def test_rds(self): known = { 'DBSecurityGroup': { 'Properties': { - 'DBSecurityGroupIngress': [{'CIDRIP': { 'Fn::FindInMap': ['SubnetConfig', 'VPC', 'CIDR'] }}], - 'EC2VpcId': {'Ref': 'VPC'}, - 'GroupDescription': 'EC2 Access'}, - 'Type': 'AWS::RDS::DBSecurityGroup'}, - 'RDSInstance': { - 'DependsOn': 'DBSecurityGroup', - 'Properties': { - 'AllocatedStorage': 5, - 'AllowMajorVersionUpgrade': False, - 'AutoMinorVersionUpgrade': False, - 'BackupRetentionPeriod': 1, - 'DBInstanceClass': 'db.t2.micro', - 'DBInstanceIdentifier': 'test-dev', - 'DBName': 'test', - 'DBSecurityGroups': [{'Ref': 'DBSecurityGroup'}], - 'DBSubnetGroupName': {'Ref': 'RDSSubnetGroup'}, - 'Engine': 'postgres', - 'EngineVersion': '9.3.5', - 'MasterUserPassword': 'testpassword', - 'MasterUsername': 'testuser', - 'MultiAZ': False, - 'PubliclyAccessible': False, - 'StorageType': 'gp2'}, - 'Type': 'AWS::RDS::DBInstance'}, - 'RDSSubnetGroup': { - 'Properties': { - 'DBSubnetGroupDescription': 'VPC Subnets', - 'SubnetIds': [{'Ref': 'SubnetA'}, {'Ref': 'SubnetB'}, {'Ref': 'SubnetC'}]}, - 'Type': 'AWS::RDS::DBSubnetGroup'} - } - + 'DBSecurityGroupIngress': [{'CIDRIP': {'Fn::FindInMap': ['SubnetConfig', 'VPC', 'CIDR']}}], + 'EC2VpcId': {'Ref': 'VPC'}, + 'GroupDescription': 'EC2 Access'}, + 'Type': 'AWS::RDS::DBSecurityGroup'}, + 'RDSInstance': { + 'DependsOn': 'DBSecurityGroup', + 'Properties': { + 'AllocatedStorage': 5, + 'AllowMajorVersionUpgrade': False, + 'AutoMinorVersionUpgrade': False, + 'BackupRetentionPeriod': 1, + 'DBInstanceClass': 'db.t2.micro', + 'DBInstanceIdentifier': 'test-dev', + 'DBName': 'test', + 'DBSecurityGroups': [{'Ref': 'DBSecurityGroup'}], + 'DBSubnetGroupName': {'Ref': 'RDSSubnetGroup'}, + 'Engine': 'postgres', + 'EngineVersion': '9.3.5', + 'MasterUserPassword': 'testpassword', + 'MasterUsername': 'testuser', + 'MultiAZ': False, + 'PubliclyAccessible': False, + 'StorageType': 'gp2'}, + 'Type': 'AWS::RDS::DBInstance'}, + 'RDSSubnetGroup': { + 'Properties': { + 'DBSubnetGroupDescription': 'VPC Subnets', + 'SubnetIds': [{'Ref': 'SubnetA'}, {'Ref': 'SubnetB'}, {'Ref': 'SubnetC'}]}, + 'Type': 'AWS::RDS::DBSubnetGroup'} + } config = ConfigParser( ProjectConfig( 'tests/sample-project.yaml', 'dev', - 'tests/sample-project-passwords.yaml').config,'my-stack-name') + 'tests/sample-project-passwords.yaml').config, 'my-stack-name') self.assertEquals(known, config.rds()) def test_elb(self): @@ -284,7 +287,7 @@ def test_elb(self): config = ConfigParser( ProjectConfig( 'tests/sample-project.yaml', - 'dev').config,'my-stack-name') + 'dev').config, 'my-stack-name') elb_cfg, elb_sgs = config.elb() compare(expected_resources, elb_cfg) @@ -336,28 +339,28 @@ def test_elb_custom_sg(self): compare(expected_sgs, elb_sgs) - [elb] = (e.values()[0] for e in elb_cfg if e.has_key('ELBtestdevexternal')) + [elb] = (e.values()[0] for e in elb_cfg if 'ELBtestdevexternal' in e) compare(elb['Properties']['SecurityGroups'], [{u'Ref': u'SGName'}]) def test_cf_includes(self): project_config = ProjectConfig('tests/sample-project.yaml', - 'dev', + 'dev', 'tests/sample-project-passwords.yaml') project_config.config['includes'] = ['tests/sample-include.json'] known_outputs = { - "dbhost": { - "Description": "RDS Hostname", - "Value": {"Fn::GetAtt" : [ "RDSInstance" , "Endpoint.Address" ]} - }, - "dbport": { - "Description": "RDS Port", - "Value": {"Fn::GetAtt" : [ "RDSInstance" , "Endpoint.Port" ]} - }, - "someoutput":{ - "Description": "For tests", - "Value": "BLAHBLAH" - } + "dbhost": { + "Description": "RDS Hostname", + "Value": {"Fn::GetAtt": ["RDSInstance", "Endpoint.Address"]} + }, + "dbport": { + "Description": "RDS Port", + "Value": {"Fn::GetAtt": ["RDSInstance", "Endpoint.Port"]} + }, + "someoutput": { + "Description": "For tests", + "Value": "BLAHBLAH" + } } config = ConfigParser(project_config.config, 'my-stack-name') cfg = json.loads(config.process()) @@ -384,17 +387,17 @@ def test_elb_missing_cert(self): 'certificate_name': 'my-cert', 'scheme': 'internet-facing', 'listeners': [ - { 'LoadBalancerPort': 80, - 'InstancePort': 80, - 'Protocol': 'TCP' - }, - { 'LoadBalancerPort': 443, - 'InstancePort': 443, - 'Protocol': 'HTTPS' - }, + {'LoadBalancerPort': 80, + 'InstancePort': 80, + 'Protocol': 'TCP' + }, + {'LoadBalancerPort': 443, + 'InstancePort': 443, + 'Protocol': 'HTTPS' + }, ], }] - config = ConfigParser(project_config.config,'my-stack-name') + config = ConfigParser(project_config.config, 'my-stack-name') with self.assertRaises(errors.CfnConfigError): config.elb() @@ -408,17 +411,17 @@ def test_elb_missing_cert_name(self): 'hosted_zone': 'kyrtest.foo.bar.', 'scheme': 'internet-facing', 'listeners': [ - { 'LoadBalancerPort': 80, - 'InstancePort': 80, - 'Protocol': 'TCP' - }, - { 'LoadBalancerPort': 443, - 'InstancePort': 443, - 'Protocol': 'HTTPS' - }, + {'LoadBalancerPort': 80, + 'InstancePort': 80, + 'Protocol': 'TCP' + }, + {'LoadBalancerPort': 443, + 'InstancePort': 443, + 'Protocol': 'HTTPS' + }, ], }] - config = ConfigParser(project_config.config,'my-stack-name') + config = ConfigParser(project_config.config, 'my-stack-name') with self.assertRaises(errors.CfnConfigError): config.elb() @@ -426,36 +429,35 @@ def test_elb_with_ssl(self): self.maxDiff = None - known = [ {'ELBdev_dockerregistryservice': {'Properties': {'Listeners': [{'InstancePort': 80, - 'LoadBalancerPort': 80, - 'Protocol': 'TCP'}, - {'InstancePort': 443, + 'LoadBalancerPort': 80, + 'Protocol': 'TCP'}, + {'InstancePort': 443, 'LoadBalancerPort': 443, 'Protocol': 'HTTPS', 'SSLCertificateId': {'Fn::Join': ['', - ['arn:aws:iam::', - {'Ref': 'AWS::AccountId'}, - ':server-certificate/', - 'my-cert-my-stack-name']]}}], - 'LoadBalancerName': 'ELB-dev_docker-registryservice', - 'SecurityGroups': [{'Ref':'DefaultSGdev_dockerregistryservice'}], - 'Scheme': 'internet-facing', - 'Subnets': [{'Ref': 'SubnetA'}, - {'Ref': 'SubnetB'}, - {'Ref': 'SubnetC'}]}, - 'Type': 'AWS::ElasticLoadBalancing::LoadBalancer'}}, - {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', - 'HostedZoneName': 'kyrtest.foo.bar.', - 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'DNSName']}, - 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'CanonicalHostedZoneNameID']}}, - 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', - 'Type': 'A'}]}, - 'Type': 'AWS::Route53::RecordSetGroup'}} - ] + ['arn:aws:iam::', + {'Ref': 'AWS::AccountId'}, + ':server-certificate/', + 'my-cert-my-stack-name']]}}], + 'LoadBalancerName': 'ELB-dev_docker-registryservice', + 'SecurityGroups': [{'Ref': 'DefaultSGdev_dockerregistryservice'}], + 'Scheme': 'internet-facing', + 'Subnets': [{'Ref': 'SubnetA'}, + {'Ref': 'SubnetB'}, + {'Ref': 'SubnetC'}]}, + 'Type': 'AWS::ElasticLoadBalancing::LoadBalancer'}}, + {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', + 'HostedZoneName': 'kyrtest.foo.bar.', + 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', + 'DNSName']}, + 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', + 'CanonicalHostedZoneNameID']}}, + 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', + 'Type': 'A'}]}, + 'Type': 'AWS::Route53::RecordSetGroup'}} + ] project_config = ProjectConfig('tests/sample-project.yaml', 'dev') # Ugh. Fixtures please? @@ -465,17 +467,17 @@ def test_elb_with_ssl(self): 'scheme': 'internet-facing', 'certificate_name': 'my-cert', 'listeners': [ - { 'LoadBalancerPort': 80, - 'InstancePort': 80, - 'Protocol': 'TCP' - }, - { 'LoadBalancerPort': 443, - 'InstancePort': 443, - 'Protocol': 'HTTPS' - }, + {'LoadBalancerPort': 80, + 'InstancePort': 80, + 'Protocol': 'TCP' + }, + {'LoadBalancerPort': 443, + 'InstancePort': 443, + 'Protocol': 'HTTPS' + }, ], }] - config = ConfigParser(project_config.config,'my-stack-name') + config = ConfigParser(project_config.config, 'my-stack-name') elb_cfg, elb_sgs = config.elb() self.assertEquals(known, elb_cfg) @@ -484,28 +486,28 @@ def test_elb_with_reserved_chars(self): self.maxDiff = None known = [ {'ELBdev_dockerregistryservice': {'Properties': {'Listeners': [{'InstancePort': 80, - 'LoadBalancerPort': 80, - 'Protocol': 'TCP'}, - {'InstancePort': 443, + 'LoadBalancerPort': 80, + 'Protocol': 'TCP'}, + {'InstancePort': 443, 'LoadBalancerPort': 443, 'Protocol': 'TCP'}], - 'LoadBalancerName': 'ELB-dev_docker-registryservice', - 'SecurityGroups': [{'Ref':'DefaultSGdev_dockerregistryservice'}], - 'Scheme': 'internet-facing', - 'Subnets': [{'Ref': 'SubnetA'}, - {'Ref': 'SubnetB'}, - {'Ref': 'SubnetC'}]}, - 'Type': 'AWS::ElasticLoadBalancing::LoadBalancer'}}, - {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', - 'HostedZoneName': 'kyrtest.foo.bar.', - 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'DNSName']}, - 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', - 'CanonicalHostedZoneNameID']}}, - 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', - 'Type': 'A'}]}, - 'Type': 'AWS::Route53::RecordSetGroup'}} - ] + 'LoadBalancerName': 'ELB-dev_docker-registryservice', + 'SecurityGroups': [{'Ref': 'DefaultSGdev_dockerregistryservice'}], + 'Scheme': 'internet-facing', + 'Subnets': [{'Ref': 'SubnetA'}, + {'Ref': 'SubnetB'}, + {'Ref': 'SubnetC'}]}, + 'Type': 'AWS::ElasticLoadBalancing::LoadBalancer'}}, + {'DNSdev_dockerregistryservice': {'Properties': {'Comment': 'Zone apex alias targeted to ElasticLoadBalancer.', + 'HostedZoneName': 'kyrtest.foo.bar.', + 'RecordSets': [{'AliasTarget': {'DNSName': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', + 'DNSName']}, + 'HostedZoneId': {'Fn::GetAtt': ['ELBdev_dockerregistryservice', + 'CanonicalHostedZoneNameID']}}, + 'Name': 'dev_docker-registry.service.kyrtest.foo.bar.', + 'Type': 'A'}]}, + 'Type': 'AWS::Route53::RecordSetGroup'}} + ] project_config = ProjectConfig('tests/sample-project.yaml', 'dev') # Ugh. Fixtures please? @@ -514,17 +516,17 @@ def test_elb_with_reserved_chars(self): 'hosted_zone': 'kyrtest.foo.bar.', 'scheme': 'internet-facing', 'listeners': [ - { 'LoadBalancerPort': 80, - 'InstancePort': 80, - 'Protocol': 'TCP' - }, - { 'LoadBalancerPort': 443, - 'InstancePort': 443, - 'Protocol': 'TCP' - }, + {'LoadBalancerPort': 80, + 'InstancePort': 80, + 'Protocol': 'TCP' + }, + {'LoadBalancerPort': 443, + 'InstancePort': 443, + 'Protocol': 'TCP' + }, ], }] - config = ConfigParser(project_config.config,'my-stack-name') + config = ConfigParser(project_config.config, 'my-stack-name') elb_cfg, elb_sgs = config.elb() self.assertEquals(known, elb_cfg) @@ -532,26 +534,25 @@ def test_ec2(self): self.maxDiff = None - known = { - 'BaseHostLaunchConfig': {'Properties': {'AssociatePublicIpAddress': 'true', - 'BlockDeviceMappings': [{'DeviceName': '/dev/sda1', + 'BaseHostLaunchConfig': {'Properties': {'AssociatePublicIpAddress': 'true', + 'BlockDeviceMappings': [{'DeviceName': '/dev/sda1', 'Ebs': {'VolumeSize': 10}}, {'DeviceName': '/dev/sdf', 'Ebs': {'VolumeSize': 10}}], - 'IamInstanceProfile': {'Ref': 'InstanceProfile'}, - 'ImageId': {'Fn::FindInMap': ['AWSRegion2AMI', - {'Ref': 'AWS::Region'}, - 'AMI']}, - 'InstanceType': 't2.micro', - 'KeyName': 'default', - 'SecurityGroups': [{'Ref':'BaseHostSG'},{'Ref':'AnotherSG'}], - 'UserData': {'Fn::Base64': {'Fn::Join': ['', - ['#!/bin/bash -xe\n', - '#do nothing for now']]}}}, - 'Type': 'AWS::AutoScaling::LaunchConfiguration'}, - 'BaseHostSG': {'Properties': {'GroupDescription': 'BaseHost Security Group', - 'SecurityGroupIngress': [{'CidrIp': '0.0.0.0/0', + 'IamInstanceProfile': {'Ref': 'InstanceProfile'}, + 'ImageId': {'Fn::FindInMap': ['AWSRegion2AMI', + {'Ref': 'AWS::Region'}, + 'AMI']}, + 'InstanceType': 't2.micro', + 'KeyName': 'default', + 'SecurityGroups': [{'Ref': 'BaseHostSG'}, {'Ref': 'AnotherSG'}], + 'UserData': {'Fn::Base64': {'Fn::Join': ['', + ['#!/bin/bash -xe\n', + '#do nothing for now']]}}}, + 'Type': 'AWS::AutoScaling::LaunchConfiguration'}, + 'BaseHostSG': {'Properties': {'GroupDescription': 'BaseHost Security Group', + 'SecurityGroupIngress': [{'CidrIp': '0.0.0.0/0', 'FromPort': 22, 'IpProtocol': 'tcp', 'ToPort': 22}, @@ -559,21 +560,21 @@ def test_ec2(self): 'FromPort': 80, 'IpProtocol': 'tcp', 'ToPort': 80}], + 'VpcId': {'Ref': 'VPC'}}, + 'Type': 'AWS::EC2::SecurityGroup'}, + 'AnotherSG': {'Properties': {'GroupDescription': 'BaseHost Security Group', + 'SecurityGroupIngress': [{'SourceSecurityGroupName': {'Ref': 'BaseHostSG'}, + 'FromPort': 443, + 'IpProtocol': 'tcp', + 'ToPort': 443}], 'VpcId': {'Ref': 'VPC'}}, - 'Type': 'AWS::EC2::SecurityGroup'}, - 'AnotherSG': {'Properties': {'GroupDescription': 'BaseHost Security Group', - 'SecurityGroupIngress': [{ 'SourceSecurityGroupName': {'Ref':'BaseHostSG'}, - 'FromPort': 443, - 'IpProtocol': 'tcp', - 'ToPort': 443}], - 'VpcId': {'Ref': 'VPC'}}, - 'Type': 'AWS::EC2::SecurityGroup'}, - 'ScalingGroup': {'Properties': {'AvailabilityZones': {'Fn::GetAZs': ''}, - 'DesiredCapacity': 1, - 'LaunchConfigurationName': {'Ref': 'BaseHostLaunchConfig'}, - 'MaxSize': 3, - 'MinSize': 0, - 'Tags': [{'Key': 'Role', + 'Type': 'AWS::EC2::SecurityGroup'}, + 'ScalingGroup': {'Properties': {'AvailabilityZones': {'Fn::GetAZs': ''}, + 'DesiredCapacity': 1, + 'LaunchConfigurationName': {'Ref': 'BaseHostLaunchConfig'}, + 'MaxSize': 3, + 'MinSize': 0, + 'Tags': [{'Key': 'Role', 'PropagateAtLaunch': True, 'Value': 'docker'}, {'Key': 'Apps', @@ -582,11 +583,11 @@ def test_ec2(self): {'Key': 'Env', 'PropagateAtLaunch': True, 'Value': 'dev'}], - 'VPCZoneIdentifier': [{'Ref': 'SubnetA'}, + 'VPCZoneIdentifier': [{'Ref': 'SubnetA'}, {'Ref': 'SubnetB'}, {'Ref': 'SubnetC'}]}, - 'Type': 'AWS::AutoScaling::AutoScalingGroup'} - } + 'Type': 'AWS::AutoScaling::AutoScalingGroup'} + } config = ConfigParser( ProjectConfig( @@ -599,7 +600,8 @@ def test_ec2_with_no_block_device_specified(self): project_config = ProjectConfig('tests/sample-project.yaml', 'dev') project_config.config['ec2'].pop('block_devices') config = ConfigParser(project_config.config, 'my-stack-name') - config_output = config.ec2()['BaseHostLaunchConfig']['Properties']['BlockDeviceMappings'] + config_output = config.ec2()['BaseHostLaunchConfig'][ + 'Properties']['BlockDeviceMappings'] known = [{'DeviceName': '/dev/sda1', 'Ebs': {'VolumeSize': 20}}] self.assertEquals(known, config_output)