From 9058be757fbd64267bbd9a4dfb9864a7da5857d5 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Mon, 26 Nov 2012 13:07:51 +1300 Subject: [PATCH] Convert some existing templates to YAML format. This is the result of running: python tools/cfn-json2yaml templates/ and then cleaning up by hand to be more consistant, readable and maintainable. The following templates are enforced to parse to identical stacks in the unit tests so any fundamental change to one must be made to the other. Quantum.template Quantum.yaml WordPress_Single_Instance.template WordPress_Single_Instance.yaml Change-Id: Ibe05a5c5a7a5bb1861c5f84a3dc41e2d632852fd --- heat/tests/test_format.py | 63 +++++++++++ templates/Quantum.yaml | 72 ++++++++++++ templates/WordPress_Single_Instance.yaml | 135 +++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 templates/Quantum.yaml create mode 100644 templates/WordPress_Single_Instance.yaml diff --git a/heat/tests/test_format.py b/heat/tests/test_format.py index a52c712f..2308e98d 100644 --- a/heat/tests/test_format.py +++ b/heat/tests/test_format.py @@ -94,3 +94,66 @@ Outputs: {} tpl1 = format.parse_to_template(yaml1) tpl2 = format.parse_to_template(yaml2) self.assertEqual(tpl1, tpl2) + + +@attr(tag=['unit']) +class JsonYamlResolvedCompareTest(unittest.TestCase): + + def setUp(self): + self.longMessage = True + self.maxDiff = None + + def load_template(self, file_name): + self.path = os.path.dirname(os.path.realpath(__file__)).\ + replace('heat/tests', 'templates') + f = open("%s/%s" % (self.path, file_name)) + t = format.parse_to_template(f.read()) + f.close() + return t + + def parse_stack(self, t, parameters): + ctx = context.RequestContext.from_dict({ + 'tenant': 'test_tenant', + 'username': 'test_username', + 'password': 'password', + 'auth_url': 'http://localhost:5000/v2.0'}) + template = parser.Template(t) + params = parser.Parameters('test_stack', template, parameters) + stack = parser.Stack(ctx, 'test_stack', parser.Template(t), + stack_id=-1, parameters=params) + + return stack + + def compare_stacks(self, json_file, yaml_file, parameters): + t1 = self.load_template(json_file) + format.default_for_missing(t1, 'AWSTemplateFormatVersion', + format.CFN_VERSIONS) + del(t1[u'AWSTemplateFormatVersion']) + + t2 = self.load_template(yaml_file) + del(t2[u'HeatTemplateFormatVersion']) + + stack1 = self.parse_stack(t1, parameters) + stack2 = self.parse_stack(t2, parameters) + + # compare resources separately so that resolved static data + # is compared + t1nr = dict(stack1.t.t) + del(t1nr['Resources']) + + t2nr = dict(stack2.t.t) + del(t2nr['Resources']) + self.assertEqual(t1nr, t2nr) + + self.assertEquals(set(stack1.resources.keys()), + set(stack2.resources.keys())) + for key in stack1.resources: + self.assertEqual(stack1.resources[key].t, stack2.resources[key].t) + + def test_quantum_resolved(self): + self.compare_stacks('Quantum.template', 'Quantum.yaml', {}) + + def test_wordpress_resolved(self): + self.compare_stacks('WordPress_Single_Instance.template', + 'WordPress_Single_Instance.yaml', + {'KeyName': 'test'}) diff --git a/templates/Quantum.yaml b/templates/Quantum.yaml new file mode 100644 index 00000000..61ea1448 --- /dev/null +++ b/templates/Quantum.yaml @@ -0,0 +1,72 @@ +HeatTemplateFormatVersion: '2012-12-12' +Description: Template to test Quantum resources +Resources: + network: + Type: OS::Quantum::Net + Properties: {name: the_network} + unnamed_network: + Type: 'OS::Quantum::Net' + admin_down_network: + Type: OS::Quantum::Net + Properties: {admin_state_up: false} + subnet: + Type: OS::Quantum::Subnet + Properties: + network_id: {Ref: network} + ip_version: 4 + cidr: 10.0.3.0/24 + allocation_pools: + - {end: 10.0.3.150, start: 10.0.3.20} + port: + Type: OS::Quantum::Port + Properties: + device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0 + name: port1 + network_id: {Ref: network} + fixed_ips: + - subnet_id: {Ref: subnet} + ip_address: 10.0.3.21 + router: + Type: 'OS::Quantum::Router' + router_interface: + Type: OS::Quantum::RouterInterface + Properties: + router_id: {Ref: router} + subnet_id: {Ref: subnet} +Outputs: + the_network_status: + Value: + Fn::GetAtt: [network, status] + Description: Status of network + port_device_owner: + Value: + Fn::GetAtt: [port, device_owner] + Description: Device owner of the port + port_fixed_ips: + Value: + Fn::GetAtt: [port, fixed_ips] + Description: Fixed IPs of the port + port_mac_address: + Value: + Fn::GetAtt: [port, mac_address] + Description: MAC address of the port + port_status: + Value: + Fn::GetAtt: [port, status] + Description: Status of the port + port_show: + Value: + Fn::GetAtt: [port, show] + Description: All attributes for port + subnet_show: + Value: + Fn::GetAtt: [subnet, show] + Description: All attributes for subnet + network_show: + Value: + Fn::GetAtt: [network, show] + Description: All attributes for network + router_show: + Value: + Fn::GetAtt: [router, show] + Description: All attributes for router diff --git a/templates/WordPress_Single_Instance.yaml b/templates/WordPress_Single_Instance.yaml new file mode 100644 index 00000000..f2fc34cb --- /dev/null +++ b/templates/WordPress_Single_Instance.yaml @@ -0,0 +1,135 @@ +HeatTemplateFormatVersion: '2012-12-12' +Description: 'AWS CloudFormation Sample Template WordPress_Single_Instance: + WordPress is web software you can use to create a beautiful website or blog. This + template installs a single-instance WordPress deployment using a local MySQL database + to store the data.' +Parameters: + KeyName: + Description: Name of an existing EC2 KeyPair to enable SSH access to the instances + Type: String + InstanceType: + Description: WebServer EC2 instance type + Type: String + Default: m1.large + AllowedValues: [t1.micro, m1.small, m1.large, m1.xlarge, m2.xlarge, + m2.2xlarge, m2.4xlarge, c1.medium, c1.xlarge, cc1.4xlarge] + ConstraintDescription: must be a valid EC2 instance type. + DBName: {Default: wordpress, Description: The + WordPress database name, Type: String, MinLength: '1', + MaxLength: '64', AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*', + ConstraintDescription: must begin with a letter and contain only + alphanumeric characters.} + DBUsername: {Default: admin, NoEcho: 'true', + Description: The WordPress database admin account username, Type: String, + MinLength: '1', MaxLength: '16', AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*', + ConstraintDescription: must begin with a letter and contain only + alphanumeric characters.} + DBPassword: {Default: admin, NoEcho: 'true', + Description: The WordPress database admin account password, Type: String, + MinLength: '1', MaxLength: '41', AllowedPattern: '[a-zA-Z0-9]*', + ConstraintDescription: must contain only alphanumeric characters.} + DBRootPassword: {Default: admin, NoEcho: 'true', + Description: Root password for MySQL, Type: String, + MinLength: '1', MaxLength: '41', AllowedPattern: '[a-zA-Z0-9]*', + ConstraintDescription: must contain only alphanumeric characters.} + LinuxDistribution: + Default: F17 + Description: Distribution of choice + Type: String + AllowedValues: [F16, F17, U10, RHEL-6.1, RHEL-6.2, RHEL-6.3] +Mappings: + AWSInstanceType2Arch: + t1.micro: {Arch: '32'} + m1.small: {Arch: '32'} + m1.large: {Arch: '64'} + m1.xlarge: {Arch: '64'} + m2.xlarge: {Arch: '64'} + m2.2xlarge: {Arch: '64'} + m2.4xlarge: {Arch: '64'} + c1.medium: {Arch: '32'} + c1.xlarge: {Arch: '64'} + cc1.4xlarge: {Arch: '64'} + DistroArch2AMI: + F16: {'32': F16-i386-cfntools, '64': F16-x86_64-cfntools} + F17: {'32': F17-i386-cfntools, '64': F17-x86_64-cfntools} + U10: {'32': U10-i386-cfntools, '64': U10-x86_64-cfntools} + RHEL-6.1: {'32': rhel61-i386-cfntools, '64': rhel61-x86_64-cfntools} + RHEL-6.2: {'32': rhel62-i386-cfntools, '64': rhel62-x86_64-cfntools} + RHEL-6.3: {'32': rhel63-i386-cfntools, '64': rhel63-x86_64-cfntools} +Resources: + WikiDatabase: + Type: AWS::EC2::Instance + Metadata: + AWS::CloudFormation::Init: + config: + packages: + yum: + mysql: [] + mysql-server: [] + httpd: [] + wordpress: [] + services: + systemd: + mysqld: {enabled: 'true', ensureRunning: 'true'} + httpd: {enabled: 'true', ensureRunning: 'true'} + Properties: + ImageId: + Fn::FindInMap: + - DistroArch2AMI + - {Ref: LinuxDistribution} + - Fn::FindInMap: + - AWSInstanceType2Arch + - {Ref: InstanceType} + - Arch + InstanceType: {Ref: InstanceType} + KeyName: {Ref: KeyName} + UserData: + Fn::Base64: + Fn::Join: + - '' + - - |- + #!/bin/bash -v + /opt/aws/bin/cfn-init + # Setup MySQL root password and create a user + mysqladmin -u root password ' + - {Ref: DBRootPassword} + - |- + ' + cat << EOF | mysql -u root --password=' + - {Ref: DBRootPassword} + - |- + ' + CREATE DATABASE + - {Ref: DBName} + - |- + ; + GRANT ALL PRIVILEGES ON + - {Ref: DBName} + - .* TO " + - {Ref: DBUsername} + - |- + "@"localhost" + IDENTIFIED BY " + - {Ref: DBPassword} + - |- + "; + FLUSH PRIVILEGES; + EXIT + EOF + sed --in-place --e s/database_name_here/ + - {Ref: DBName} + - / --e s/username_here/ + - {Ref: DBUsername} + - / --e s/password_here/ + - {Ref: DBPassword} + - | + / /usr/share/wordpress/wp-config.php +Outputs: + WebsiteURL: + Value: + Fn::Join: + - '' + - - http:// + - Fn::GetAtt: [WikiDatabase, PublicIp] + - /wordpress + Description: URL for Wordpress wiki -- 2.45.2