spec/dslh_spec.rb in dslh-0.2.0 vs spec/dslh_spec.rb in dslh-0.2.1

- old
+ new

@@ -1,10 +1,14 @@ describe Dslh do let(:drupal_multi_az_template) do open(File.expand_path('../Drupal_Multi_AZ.template', __FILE__)) {|f| f.read } end + let(:drupal_single_instance_template) do + open(File.expand_path('../Drupal_Single_Instance.template', __FILE__)) {|f| f.read } + end + it 'should be empty hash' do h = Dslh.eval {} expect(h).to eq({}) end @@ -1090,17 +1094,17 @@ it 'should convert json to dsl with key_conf (return Proc)' do template = JSON.parse(drupal_multi_az_template) exclude_key = proc do |k| k = k.to_s.gsub('::', '__') - k !~ /\A[_a-z]\w+\Z/i and k !~ %r|(?:/[:graph:]+)+| + k !~ /\A[_a-z]\w+\Z/i and k !~ %r|\A/\S*\Z| end key_conv = proc do |k| k = k.to_s - if k =~ %r|(?:/[:graph:]+)+| + if k =~ %r|\A/\S*\Z| proc do |v, nested| if nested "_path(#{k.inspect}) #{v}" else "_path #{k.inspect}, #{v}" @@ -1683,8 +1687,371 @@ ] end Description "Drupal Website" end end -EOS + EOS + end + + it 'should convert json to dsl with key_conf (use drupal_single_instance_template)' do + template = JSON.parse(drupal_single_instance_template) + + exclude_key = proc do |k| + k = k.to_s.gsub('::', '__') + k !~ /\A[_a-z]\w+\Z/i and k !~ %r|\A/\S*\Z| + end + + key_conv = proc do |k| + k = k.to_s + + if k =~ %r|\A/\S*\Z| + proc do |v, nested| + if nested + "_path(#{k.inspect}) #{v}" + else + "_path #{k.inspect}, #{v}" + end + end + else + k.gsub('::', '__') + end + end + + dsl = Dslh.deval(template, :key_conv => key_conv, :exclude_key => exclude_key) + + expect(dsl).to eq(<<-'EOS') +AWSTemplateFormatVersion "2010-09-09" +Description "AWS CloudFormation Sample Template Drupal_Single_Instance. Drupal is an open source content management platform powering millions of websites and applications. This template installs a singe instance deployment with a local MySQL database for storage. It uses the AWS CloudFormation bootstrap scripts to install packages and files at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template." +Parameters do + KeyName do + Description "Name of an existing EC2 KeyPair to enable SSH access to the instances" + Type "String" + MinLength "1" + MaxLength "255" + AllowedPattern "[\\x20-\\x7E]*" + ConstraintDescription "can contain only ASCII characters." + end + InstanceType do + Description "WebServer EC2 instance type" + Type "String" + Default "m1.small" + AllowedValues "t1.micro", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.xlarge", "m3.2xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge", "cc2.8xlarge", "cg1.4xlarge" + ConstraintDescription "must be a valid EC2 instance type." + end + SiteName do + Default "My Site" + Description "The name of the Drupal Site" + Type "String" + end + SiteEMail do + Description "EMail for site adminitrator" + Type "String" + end + SiteAdmin do + Description "The Drupal site 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." + end + SitePassword do + NoEcho "true" + Description "The Drupal site admin account password" + Type "String" + MinLength "1" + MaxLength "41" + AllowedPattern "[a-zA-Z0-9]*" + ConstraintDescription "must contain only alphanumeric characters." + end + DBName do + Default "drupaldb" + Description "The Drupal 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." + end + DBUsername do + Default "admin" + NoEcho "true" + Description "The Drupal 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." + end + DBPassword do + Default "admin" + NoEcho "true" + Description "The Drupal database admin account password" + Type "String" + MinLength "1" + MaxLength "41" + AllowedPattern "[a-zA-Z0-9]*" + ConstraintDescription "must contain only alphanumeric characters." + end + DBRootPassword do + NoEcho "true" + Description "Root password for MySQL" + Type "String" + MinLength "1" + MaxLength "41" + AllowedPattern "[a-zA-Z0-9]*" + ConstraintDescription "must contain only alphanumeric characters." + end + SSHLocation do + Description "The IP address range that can be used to SSH to the EC2 instances" + Type "String" + MinLength "9" + MaxLength "18" + Default "0.0.0.0/0" + AllowedPattern "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" + ConstraintDescription "must be a valid IP CIDR range of the form x.x.x.x/x." + end +end +Mappings do + AWSInstanceType2Arch( + {"t1.micro"=>{"Arch"=>"64"}, + "m1.small"=>{"Arch"=>"64"}, + "m1.medium"=>{"Arch"=>"64"}, + "m1.large"=>{"Arch"=>"64"}, + "m1.xlarge"=>{"Arch"=>"64"}, + "m2.xlarge"=>{"Arch"=>"64"}, + "m2.2xlarge"=>{"Arch"=>"64"}, + "m2.4xlarge"=>{"Arch"=>"64"}, + "m3.xlarge"=>{"Arch"=>"64"}, + "m3.2xlarge"=>{"Arch"=>"64"}, + "c1.medium"=>{"Arch"=>"64"}, + "c1.xlarge"=>{"Arch"=>"64"}, + "cc1.4xlarge"=>{"Arch"=>"64HVM"}, + "cc2.8xlarge"=>{"Arch"=>"64HVM"}, + "cg1.4xlarge"=>{"Arch"=>"64HVM"}}) + AWSRegionArch2AMI( + {"us-east-1"=> + {"32"=>"ami-a0cd60c9", "64"=>"ami-aecd60c7", "64HVM"=>"ami-a8cd60c1"}, + "us-west-2"=> + {"32"=>"ami-46da5576", "64"=>"ami-48da5578", "64HVM"=>"NOT_YET_SUPPORTED"}, + "us-west-1"=> + {"32"=>"ami-7d4c6938", "64"=>"ami-734c6936", "64HVM"=>"NOT_YET_SUPPORTED"}, + "eu-west-1"=> + {"32"=>"ami-61555115", "64"=>"ami-6d555119", "64HVM"=>"ami-67555113"}, + "ap-southeast-1"=> + {"32"=>"ami-220b4a70", "64"=>"ami-3c0b4a6e", "64HVM"=>"NOT_YET_SUPPORTED"}, + "ap-southeast-2"=> + {"32"=>"ami-b3990e89", "64"=>"ami-bd990e87", "64HVM"=>"NOT_YET_SUPPORTED"}, + "ap-northeast-1"=> + {"32"=>"ami-2a19aa2b", "64"=>"ami-2819aa29", "64HVM"=>"NOT_YET_SUPPORTED"}, + "sa-east-1"=> + {"32"=>"ami-f836e8e5", "64"=>"ami-fe36e8e3", "64HVM"=>"NOT_YET_SUPPORTED"}}) +end +Resources do + WebServer do + Type "AWS::EC2::Instance" + Metadata do + AWS__CloudFormation__Init do + config do + packages do + yum( + {"httpd"=>[], + "php"=>[], + "php-mysql"=>[], + "php-gd"=>[], + "php-xml"=>[], + "php-mbstring"=>[], + "mysql"=>[], + "mysql-server"=>[], + "mysql-devel"=>[], + "mysql-libs"=>[]}) + end + sources do + _path "/var/www/html", "http://ftp.drupal.org/files/projects/drupal-7.8.tar.gz" + _path "/home/ec2-user", "http://ftp.drupal.org/files/projects/drush-7.x-4.5.tar.gz" + end + files do + _path("/tmp/setup.mysql") do + content do + Fn__Join [ + "", + ["CREATE DATABASE ", + {"Ref"=>"DBName"}, + ";\n", + "CREATE USER '", + {"Ref"=>"DBUsername"}, + "'@'localhost' IDENTIFIED BY '", + {"Ref"=>"DBPassword"}, + "';\n", + "GRANT ALL ON ", + {"Ref"=>"DBName"}, + ".* TO '", + {"Ref"=>"DBUsername"}, + "'@'localhost';\n", + "FLUSH PRIVILEGES;\n"] + ] + end + mode "000644" + owner "root" + group "root" + end + end + services do + sysvinit do + httpd do + enabled "true" + ensureRunning "true" + end + mysqld do + enabled "true" + ensureRunning "true" + end + sendmail do + enabled "false" + ensureRunning "false" + end + end + end + end + end + end + Properties do + ImageId do + Fn__FindInMap [ + "AWSRegionArch2AMI", + _{ + Ref "AWS::Region" + }, + _{ + Fn__FindInMap [ + "AWSInstanceType2Arch", + _{ + Ref "InstanceType" + }, + "Arch" + ] + } + ] + end + InstanceType do + Ref "InstanceType" + end + SecurityGroups [ + _{ + Ref "WebServerSecurityGroup" + } + ] + KeyName do + Ref "KeyName" + end + UserData do + Fn__Base64 do + Fn__Join [ + "", + ["#!/bin/bash -v\n", + "yum update -y aws-cfn-bootstrap\n", + "# Helper function\n", + "function error_exit\n", + "{\n", + " /opt/aws/bin/cfn-signal -e 0 -r \"$1\" '", + {"Ref"=>"WaitHandle"}, + "'\n", + " exit 1\n", + "}\n", + "# Install Apache Web Server, MySQL, PHP and Drupal\n", + "/opt/aws/bin/cfn-init -s ", + {"Ref"=>"AWS::StackId"}, + " -r WebServer ", + " --region ", + {"Ref"=>"AWS::Region"}, + " || error_exit 'Failed to run cfn-init'\n", + "# Setup MySQL root password and create a user\n", + "mysqladmin -u root password '", + {"Ref"=>"DBRootPassword"}, + "' || error_exit 'Failed to initialize root password'\n", + "mysql -u root --password='", + {"Ref"=>"DBRootPassword"}, + "' < /tmp/setup.mysql || error_exit 'Failed to create database user'\n", + "# Make changes to Apache Web Server configuration\n", + "mv /var/www/html/drupal-7.8/* /var/www/html\n", + "mv /var/www/html/drupal-7.8/.* /var/www/html\n", + "rmdir /var/www/html/drupal-7.8\n", + "sed -i 's/AllowOverride None/AllowOverride All/g' /etc/httpd/conf/httpd.conf\n", + "service httpd restart\n", + "# Create the site in Drupal\n", + "cd /var/www/html\n", + "~ec2-user/drush/drush site-install standard --yes", + " --site-name='", + {"Ref"=>"SiteName"}, + "' --site-mail=", + {"Ref"=>"SiteEMail"}, + " --account-name=", + {"Ref"=>"SiteAdmin"}, + " --account-pass=", + {"Ref"=>"SitePassword"}, + " --db-url=mysql://", + {"Ref"=>"DBUsername"}, + ":", + {"Ref"=>"DBPassword"}, + "@localhost/", + {"Ref"=>"DBName"}, + " --db-prefix=drupal_\n", + "chown apache:apache sites/default/files\n", + "# All is well so signal success\n", + "/opt/aws/bin/cfn-signal -e 0 -r \"Drupal setup complete\" '", + {"Ref"=>"WaitHandle"}, + "'\n"] + ] + end + end + end + end + WaitHandle do + Type "AWS::CloudFormation::WaitConditionHandle" + end + WaitCondition do + Type "AWS::CloudFormation::WaitCondition" + DependsOn "WebServer" + Properties do + Handle do + Ref "WaitHandle" + end + Timeout "300" + end + end + WebServerSecurityGroup do + Type "AWS::EC2::SecurityGroup" + Properties do + GroupDescription "Enable HTTP access via port 80 and SSH access" + SecurityGroupIngress [ + _{ + IpProtocol "tcp" + FromPort "80" + ToPort "80" + CidrIp "0.0.0.0/0" + }, + _{ + IpProtocol "tcp" + FromPort "22" + ToPort "22" + CidrIp do + Ref "SSHLocation" + end + } + ] + end + end +end +Outputs do + WebsiteURL do + Value do + Fn__Join [ + "", + ["http://", {"Fn::GetAtt"=>["WebServer", "PublicDnsName"]}] + ] + end + Description "Drupal Website" + end +end + EOS end end