vominator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/.rspec +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +116 -0
- data/Rakefile +12 -0
- data/bin/vominate +12 -0
- data/circle.yml +5 -0
- data/lib/ec2.rb +12 -0
- data/lib/ec2/instances.rb +362 -0
- data/lib/ec2/security_groups.rb +314 -0
- data/lib/ec2/ssm.rb +81 -0
- data/lib/vominator/aws.rb +15 -0
- data/lib/vominator/constants.rb +53 -0
- data/lib/vominator/ec2.rb +308 -0
- data/lib/vominator/instances.rb +34 -0
- data/lib/vominator/route53.rb +125 -0
- data/lib/vominator/security_groups.rb +26 -0
- data/lib/vominator/ssm.rb +57 -0
- data/lib/vominator/version.rb +3 -0
- data/lib/vominator/vominator.rb +74 -0
- data/lib/vominator/vpc.rb +82 -0
- data/lib/vpc.rb +8 -0
- data/lib/vpc/create.rb +188 -0
- data/spec/lib/instances_spec.rb +2 -0
- data/spec/lib/vominator/aws_spec.rb +6 -0
- data/spec/lib/vominator/ec2_spec.rb +783 -0
- data/spec/lib/vominator/instances_spec.rb +96 -0
- data/spec/lib/vominator/route53_spec.rb +64 -0
- data/spec/lib/vominator/ssm_spec.rb +95 -0
- data/spec/lib/vominator/vominator_spec.rb +209 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/support/matchers/exit_with_code.rb +24 -0
- data/test/puke/cloud-configs/.gitkeep +0 -0
- data/test/puke/cloud-configs/cloud-config-example.erb +63 -0
- data/test/puke/config.yaml +16 -0
- data/test/puke/products/sample-api/instances.yaml +37 -0
- data/test/puke/products/sample-api/security_groups.yaml +19 -0
- data/test/vominator.yaml +7 -0
- data/vominator.gemspec +34 -0
- metadata +259 -0
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require 'aws-sdk'
         | 
| 2 | 
            +
            require_relative 'vominator'
         | 
| 3 | 
            +
            require_relative 'constants'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Vominator
         | 
| 6 | 
            +
              class SecurityGroups
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def self.get_security_groups(environment, product, filter=false)
         | 
| 9 | 
            +
                  if PUKE_CONFIG[environment]['products'].include? product
         | 
| 10 | 
            +
                    config_file = File.expand_path("#{VOMINATOR_CONFIG['configuration_path']}/products/#{product}/security_groups.yaml")
         | 
| 11 | 
            +
                    if filter
         | 
| 12 | 
            +
                      security_groups = Array.new
         | 
| 13 | 
            +
                      YAML.load(File.read(config_file)).each do |security_group|
         | 
| 14 | 
            +
                        if filter.include? security_group.keys[0]
         | 
| 15 | 
            +
                          security_groups.push security_group
         | 
| 16 | 
            +
                        end
         | 
| 17 | 
            +
                      end
         | 
| 18 | 
            +
                    else
         | 
| 19 | 
            +
                      security_groups = YAML.load(File.read(config_file))
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                    return security_groups if security_groups.kind_of?(Array)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            require 'aws-sdk'
         | 
| 2 | 
            +
            require_relative 'constants'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Vominator
         | 
| 5 | 
            +
              class SSM
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def self.get_documents(client,max_results=25)
         | 
| 8 | 
            +
                    resp = client.list_documents(:max_results => max_results)
         | 
| 9 | 
            +
                    documents = resp[:document_identifiers]
         | 
| 10 | 
            +
                    while resp[:next_token]
         | 
| 11 | 
            +
                      resp = client.list_documents(:next_token => resp[:next_token])
         | 
| 12 | 
            +
                      documents += resp[:document_identifiers]
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    return documents.map {|doc| doc.name }
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.describe_document(client,name)
         | 
| 19 | 
            +
                    return client.describe_document(:name => name).document
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def self.get_document(client,name)
         | 
| 23 | 
            +
                  return client.get_document(:name => name)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.put_document(client,name,data)
         | 
| 27 | 
            +
                  client.create_document(:name => name, :content => data)
         | 
| 28 | 
            +
                  sleep 2 until Vominator::SSM.describe_document(client,name).status == 'active'
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  if Vominator::SSM.describe_document(client,name).status == 'active'
         | 
| 31 | 
            +
                    return true
         | 
| 32 | 
            +
                  else
         | 
| 33 | 
            +
                    return false
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def self.associated?(client,name,instance_id)
         | 
| 38 | 
            +
                  begin
         | 
| 39 | 
            +
                    client.describe_association(:name => name, :instance_id => instance_id)
         | 
| 40 | 
            +
                    return true
         | 
| 41 | 
            +
                  rescue Aws::SSM::Errors::AssociationDoesNotExist
         | 
| 42 | 
            +
                    return false
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def self.create_association(client,name,instance_id)
         | 
| 47 | 
            +
                  client.create_association(:name => name, :instance_id => instance_id)
         | 
| 48 | 
            +
                  sleep 2 until Vominator::SSM.associated?(client,name,instance_id)
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  if Vominator::SSM.associated?(client,name,instance_id)
         | 
| 51 | 
            +
                    return true
         | 
| 52 | 
            +
                  else
         | 
| 53 | 
            +
                    return false
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            require 'yaml'
         | 
| 2 | 
            +
            require 'colored'
         | 
| 3 | 
            +
            require 'highline/import'
         | 
| 4 | 
            +
            require_relative 'version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Vominator
         | 
| 7 | 
            +
              def self.get_config(file='~/.vominator.yaml')
         | 
| 8 | 
            +
                config_file = ENV['VOMINATOR_CONFIG'] || File.expand_path(file)
         | 
| 9 | 
            +
                if File.exist?(config_file)
         | 
| 10 | 
            +
                  vominator_config = YAML.load(File.read(config_file))
         | 
| 11 | 
            +
                  return vominator_config if vominator_config.kind_of?(Hash)
         | 
| 12 | 
            +
                else
         | 
| 13 | 
            +
                  LOGGER.fatal("Unable to load vominator configuration file from #{config_file}")
         | 
| 14 | 
            +
                  return false
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def self.get_puke_config(puke_dir)
         | 
| 19 | 
            +
                if File.exist?(puke_dir)
         | 
| 20 | 
            +
                  config_file = "#{puke_dir}/config.yaml"
         | 
| 21 | 
            +
                  puke_config = YAML.load(File.read(config_file))
         | 
| 22 | 
            +
                else
         | 
| 23 | 
            +
                  raise("Unable to open puke configuration at #{puke_dir}")
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                return puke_config if puke_config.kind_of?(Hash)
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def self.get_key_pair(vominator_config)
         | 
| 29 | 
            +
                return vominator_config['key_pair_name']
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def self.get_puke_variables(environment)
         | 
| 33 | 
            +
                data = PUKE_CONFIG[environment]
         | 
| 34 | 
            +
                return data
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              def self.yesno?(prompt: 'Continue?', default: true)
         | 
| 38 | 
            +
                a = ''
         | 
| 39 | 
            +
                s = default ? '[Y/n]' : '[y/N]'
         | 
| 40 | 
            +
                d = default ? 'y' : 'n'
         | 
| 41 | 
            +
                until %w[y n].include? a
         | 
| 42 | 
            +
                  a = ask("#{prompt} #{s} ") { |q| q.limit = 1; q.case = :downcase }
         | 
| 43 | 
            +
                  a = d if a.length == 0
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
                a == 'y'
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              class Logger
         | 
| 49 | 
            +
                def self.info(message)
         | 
| 50 | 
            +
                  puts message
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def self.test(message)
         | 
| 54 | 
            +
                  puts message.cyan
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def self.error(message)
         | 
| 58 | 
            +
                  puts message.red
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                def self.fatal(message)
         | 
| 62 | 
            +
                  puts message.red
         | 
| 63 | 
            +
                  exit(1)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def self.success(message)
         | 
| 67 | 
            +
                  puts message.green
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def self.warning(message)
         | 
| 71 | 
            +
                  puts message.yellow
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            require 'aws-sdk'
         | 
| 2 | 
            +
            require_relative 'constants'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Vominator
         | 
| 5 | 
            +
              class VPC
         | 
| 6 | 
            +
                def self.get_vpc(client, vpc_id)
         | 
| 7 | 
            +
                  return client.describe_vpcs(filters: [{name: 'vpc-id', values: [vpc_id]}]).vpcs.first
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                def self.get_vpc_by_cidr(client, cidr_block)
         | 
| 10 | 
            +
                  return client.describe_vpcs(filters: [{name: 'cidr', values: [cidr_block]}]).vpcs.first
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.create_vpc(client, cidr_block, tenancy='default')
         | 
| 14 | 
            +
                  resp = client.create_vpc(:cidr_block => cidr_block, :instance_tenancy => tenancy)
         | 
| 15 | 
            +
                  sleep 2 until Vominator::VPC.get_vpc(client,resp.vpc.vpc_id).state == 'available'
         | 
| 16 | 
            +
                  return resp.vpc
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def self.get_internet_gateway(client, gateway_id)
         | 
| 20 | 
            +
                  return client.describe_internet_gateways(filters: [{name: 'internet-gateway-id', values: [gateway_id]}]).internet_gateways.first
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def self.create_internet_gateway(client)
         | 
| 24 | 
            +
                  resp = client.create_internet_gateway
         | 
| 25 | 
            +
                  return resp.internet_gateway      
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def self.attach_internet_gateway(client, gateway_id, vpc_id)
         | 
| 29 | 
            +
                  resp = client.attach_internet_gateway(internet_gateway_id: gateway_id, vpc_id: vpc_id)
         | 
| 30 | 
            +
                  sleep 2 until Vominator::VPC.get_internet_gateway(client, gateway_id).attachments.first.state == 'available'
         | 
| 31 | 
            +
                  return true
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def self.get_nat_gateway(client, gateway_id)
         | 
| 35 | 
            +
                  return client.describe_nat_gateways(filter: [{name: 'nat-gateway-id', values: [gateway_id]}]).nat_gateways.first
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
               
         | 
| 38 | 
            +
                def self.create_nat_gateway(client, subnet_id, allocation_id)
         | 
| 39 | 
            +
                  resp = client.create_nat_gateway(subnet_id: subnet_id, allocation_id: allocation_id).nat_gateway
         | 
| 40 | 
            +
                  sleep 2 until Vominator::VPC.get_nat_gateway(client, resp.nat_gateway_id).state == 'available'
         | 
| 41 | 
            +
                  return resp
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             
         | 
| 44 | 
            +
                def self.get_route_tables(client, vpc_id)
         | 
| 45 | 
            +
                  return client.describe_route_tables(filters: [{name: 'vpc-id', values: [vpc_id]}]).route_tables
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def self.get_route_table(client, route_table_id)
         | 
| 49 | 
            +
                  return client.describe_route_tables(filters: [{name: 'route-table-id', values: [route_table_id]}]).route_tables.first
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def self.create_internet_gateway_route(client, route_table_id, destination_cidr_block, gateway_id)
         | 
| 53 | 
            +
                  return client.create_route(route_table_id: route_table_id, destination_cidr_block: destination_cidr_block, gateway_id: gateway_id)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def self.create_nat_gateway_route(client, route_table_id, destination_cidr_block, nat_gateway_id)
         | 
| 57 | 
            +
                  return client.create_route(route_table_id: route_table_id, destination_cidr_block: destination_cidr_block, nat_gateway_id: nat_gateway_id)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def self.create_route_table(client, vpc_id)
         | 
| 61 | 
            +
                  resp = client.create_route_table(vpc_id: vpc_id).route_table
         | 
| 62 | 
            +
                  sleep 2 until Vominator::VPC.get_route_table(client, resp.route_table_id)
         | 
| 63 | 
            +
                  return resp
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def self.get_subnet(client, subnet_id)
         | 
| 67 | 
            +
                  return client.describe_subnets(filters: [{name: 'subnet-id', values: [subnet_id]}]).subnets.first
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def self.create_subnet(client, vpc_id, cidr_block, availability_zone)
         | 
| 71 | 
            +
                  resp = client.create_subnet(vpc_id: vpc_id, cidr_block: cidr_block, availability_zone: availability_zone).subnet
         | 
| 72 | 
            +
                  sleep 2 until Vominator::VPC.get_subnet(client, resp.subnet_id).state == 'available'
         | 
| 73 | 
            +
                  return resp
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                def self.associate_route_table(client, subnet_id, route_table_id)
         | 
| 77 | 
            +
                  return client.associate_route_table(subnet_id: subnet_id, route_table_id: route_table_id)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
    
        data/lib/vpc.rb
    ADDED
    
    
    
        data/lib/vpc/create.rb
    ADDED
    
    | @@ -0,0 +1,188 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            require 'optparse'
         | 
| 3 | 
            +
            require 'colored'
         | 
| 4 | 
            +
            require_relative '../vominator/constants'
         | 
| 5 | 
            +
            require_relative '../vominator/aws'
         | 
| 6 | 
            +
            require_relative '../vominator/vpc'
         | 
| 7 | 
            +
            require_relative '../vominator/ec2'
         | 
| 8 | 
            +
            require_relative '../vominator/route53'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            options = {}
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            OptionParser.new do |opts|
         | 
| 13 | 
            +
              opts.banner = 'Usage: vominate vpc create [options]'.yellow
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              opts.on('-eENVIRONMENT', '--environment ENVIRONMENT', 'REQUIRED: The environment which you want to create a VPC for. IE foo') do |value|
         | 
| 16 | 
            +
                options[:environment] = value
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              opts.on('--region Region', 'REQUIRED: The AWS Region that you want to create the VPC in. IE us-east-1') do |value|
         | 
| 20 | 
            +
                options[:region] = value
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              opts.on('--availability-zones AVAILABILITY ZONES', 'OPTIONAL: A comma delimited list of specific availability zones that you want to prepare. If you don\'t specify then we will use all that are available. IE us-east-1c,us-east-1d,us-east-1e') do |value|
         | 
| 24 | 
            +
                options[:availability_zones] = value
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              opts.on('--parent-domain PARENT DOMAIN', 'REQUIRED: The parent domain name that will be used to create a seperate subdomain zone file for the new environment. IE, if you provide foo.org and your environment as bar, this will yield a new Route 53 zone file called bar.foo.org') do |value|
         | 
| 28 | 
            +
                options[:parent_domain] = value
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              opts.on('--cidr-block CIDR Block', 'REQUIRED: The network block for the new environment. This must be a /16 and the second octet should be unique for this environment. IE. 10.123.0.0/16') do |value|
         | 
| 32 | 
            +
                options[:cidr_block] = value
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              
         | 
| 35 | 
            +
              #opts.on('-t', '--test', 'OPTIONAL: Test run. Show what would be changed without making any actual changes') do
         | 
| 36 | 
            +
              #  options[:test] = true
         | 
| 37 | 
            +
              #end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              #opts.on('-l', '--list', 'OPTIONAL: List out Vominator aware VPCs') do
         | 
| 40 | 
            +
              #  options[:list] = true
         | 
| 41 | 
            +
              #end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              opts.on('-d', '--debug', 'OPTIONAL: debug output') do
         | 
| 44 | 
            +
                options[:debug] = true
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              opts.on_tail(:NONE, '-h', '--help', 'OPTIONAL: Display this screen') do
         | 
| 48 | 
            +
                puts opts
         | 
| 49 | 
            +
                exit
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              begin
         | 
| 53 | 
            +
                opts.parse!
         | 
| 54 | 
            +
                ## Validate Data Inputs
         | 
| 55 | 
            +
                throw Exception unless ((options.include? :environment) && (options.include? :region) && (options.include? :parent_domain) && (options.include? :cidr_block)) || options[:list]
         | 
| 56 | 
            +
              rescue
         | 
| 57 | 
            +
                puts opts
         | 
| 58 | 
            +
                exit
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            TEST = options[:test]
         | 
| 63 | 
            +
            def test?(message)
         | 
| 64 | 
            +
              LOGGER.test(message) if TEST
         | 
| 65 | 
            +
              TEST
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            unless test?('Vominator is running in test mode. It will NOT make any changes.')
         | 
| 69 | 
            +
              LOGGER.warning('WARNING: Vominator will make changes to your environment. Please run test mode first if you are unsure.')
         | 
| 70 | 
            +
              unless Vominator.yesno?(prompt: 'Do you wish to proceed?', default: false)
         | 
| 71 | 
            +
                exit(1)
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            puke_config = Vominator.get_puke_variables(options[:environment])
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            if puke_config
         | 
| 78 | 
            +
              LOGGER.fatal("An environment with the name of #{options[:environment]} is already defined. Please choose a different name")
         | 
| 79 | 
            +
            else  
         | 
| 80 | 
            +
              puke_config = Hash.new
         | 
| 81 | 
            +
              puke_config['region_name'] = options[:region]
         | 
| 82 | 
            +
            end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            ec2_client = Aws::EC2::Client.new(region: puke_config['region_name'])
         | 
| 85 | 
            +
            r53_client = Aws::Route53::Client.new(region: puke_config['region_name'])
         | 
| 86 | 
            +
             | 
| 87 | 
            +
             | 
| 88 | 
            +
            fqdn = "#{options[:environment]}.#{options[:parent_domain]}"
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            # Couple of sanity checks before we get started....
         | 
| 91 | 
            +
            if Vominator::VPC.get_vpc_by_cidr(ec2_client, options[:cidr_block])
         | 
| 92 | 
            +
              LOGGER.warning("A VPC already exists with a netblock of #{options[:cidr_block]}. Generally you want these to be unique")
         | 
| 93 | 
            +
              unless Vominator.yesno?(prompt: 'Do you wish to proceed?', default: false)
         | 
| 94 | 
            +
                exit(1)
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end  
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            if Vominator::Route53.get_zone_by_domain(r53_client, fqdn)
         | 
| 99 | 
            +
              LOGGER.fatal("A Zonefile already exists for #{fqdn}. Please choose a different environment name")
         | 
| 100 | 
            +
            end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            if options[:availability_zones]
         | 
| 103 | 
            +
              availability_zones = options[:availability_zones].split(',')
         | 
| 104 | 
            +
            else
         | 
| 105 | 
            +
              availability_zones = Vominator::AWS.get_availability_zones(ec2_client)
         | 
| 106 | 
            +
            end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
            parent_zone = Vominator::Route53.get_zone_by_domain(r53_client, options[:parent_domain])
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            unless parent_zone
         | 
| 111 | 
            +
              LOGGER.warning("We could not find the parent zone of #{options[:parent_domain]}. You can proceed and we will provide the settings so you can manually create the entry.")
         | 
| 112 | 
            +
              unless Vominator.yesno?(prompt: 'Do you wish to proceed?', default: false)
         | 
| 113 | 
            +
                exit(1)
         | 
| 114 | 
            +
              end
         | 
| 115 | 
            +
            end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
             | 
| 118 | 
            +
            LOGGER.info("Starting the creation process. This may take a couple of minutes")
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            environment_zone = Vominator::Route53.create_zone(r53_client, fqdn)
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            if parent_zone
         | 
| 123 | 
            +
              Vominator::Route53.create_nameserver_records(r53_client,parent_zone.id, fqdn, environment_zone.delegation_set.name_servers)
         | 
| 124 | 
            +
            end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
            vpc = Vominator::VPC.create_vpc(ec2_client,options[:cidr_block])
         | 
| 127 | 
            +
             | 
| 128 | 
            +
            gateway = Vominator::VPC.create_internet_gateway(ec2_client)
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            Vominator::VPC.attach_internet_gateway(ec2_client, gateway.internet_gateway_id, vpc.vpc_id)
         | 
| 131 | 
            +
             | 
| 132 | 
            +
            public_route_table = Vominator::VPC.get_route_tables(ec2_client, vpc.vpc_id).first
         | 
| 133 | 
            +
            Vominator::EC2.tag_resource(ec2_client, public_route_table.route_table_id,[{key: 'Name', value: "dmz-#{options[:environment]}-#{options[:region]}"}])
         | 
| 134 | 
            +
              
         | 
| 135 | 
            +
            Vominator::VPC.create_internet_gateway_route(ec2_client, public_route_table.route_table_id, '0.0.0.0/0', gateway.internet_gateway_id)
         | 
| 136 | 
            +
             | 
| 137 | 
            +
            third_octet = 1
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            route_tables = Hash.new
         | 
| 140 | 
            +
            route_tables['public'] = public_route_table.route_table_id
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            availability_zones.each do |zone|
         | 
| 143 | 
            +
             | 
| 144 | 
            +
              private_route_table = Vominator::VPC.create_route_table(ec2_client, vpc.vpc_id)
         | 
| 145 | 
            +
              route_tables[zone] = private_route_table.route_table_id
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              Vominator::EC2.tag_resource(ec2_client, private_route_table.route_table_id,[{key: 'Name', value: "nat-#{options[:environment]}-#{zone}"}])
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              public_subnet_cidr_block = "#{options[:cidr_block].split('.')[0]}.#{options[:cidr_block].split('.')[1]}.#{third_octet}.0/24"
         | 
| 150 | 
            +
              public_subnet = Vominator::VPC.create_subnet(ec2_client, vpc.vpc_id, public_subnet_cidr_block, zone)
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              Vominator::VPC.associate_route_table(ec2_client, public_subnet.subnet_id, public_route_table.route_table_id)
         | 
| 153 | 
            +
             | 
| 154 | 
            +
              public_ip = Vominator::EC2.allocate_public_ip(ec2_client)
         | 
| 155 | 
            +
              nat_gateway = Vominator::VPC.create_nat_gateway(ec2_client, public_subnet.subnet_id, public_ip.allocation_id)
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              Vominator::VPC.create_nat_gateway_route(ec2_client, private_route_table.route_table_id, '0.0.0.0/0', nat_gateway.nat_gateway_id)
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              third_octet += 1
         | 
| 160 | 
            +
            end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            unless parent_zone
         | 
| 163 | 
            +
              LOGGER.warning("Parent zone not was not found in Route53. Use the below information to create the proper entries in your parent zone.")
         | 
| 164 | 
            +
              LOGGER.warning("FQDN: #{fqdn}")
         | 
| 165 | 
            +
              LOGGER.warning("Record Type: NS")
         | 
| 166 | 
            +
              LOGGER.warning("Nameservers: #{environment_zone.delegation_set.name_servers}")
         | 
| 167 | 
            +
            end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            config = {
         | 
| 170 | 
            +
                options[:environment] => {
         | 
| 171 | 
            +
                    'vpc_id' => vpc.vpc_id,
         | 
| 172 | 
            +
                    'route_tables' => route_tables,
         | 
| 173 | 
            +
                    'region_name' => options[:region],
         | 
| 174 | 
            +
                    'zone' => environment_zone.hosted_zone.id.split('/')[2],
         | 
| 175 | 
            +
                    'octet' => options[:cidr_block].split('.')[1],
         | 
| 176 | 
            +
                    'domain' => fqdn,
         | 
| 177 | 
            +
                    'linux_cloud_config_template' => 'EDIT_ME',
         | 
| 178 | 
            +
                    'linux_paravirtual_base_image' => 'EDIT_ME',
         | 
| 179 | 
            +
                    'linux_hvm_base_image' => 'EDIT_ME',
         | 
| 180 | 
            +
                    'windows_cloud_config_template' => 'EDIT_ME',
         | 
| 181 | 
            +
                    'windows_paravirtual_base_image' => 'EDIT_ME',
         | 
| 182 | 
            +
                    'windows_hvm_base_image' => 'EDIT_ME',
         | 
| 183 | 
            +
                    'chef_host' => 'EDIT_ME',
         | 
| 184 | 
            +
                    'products' => []
         | 
| 185 | 
            +
                }}
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            LOGGER.success("Append the below to your config.yaml file in your puke directory")
         | 
| 188 | 
            +
            LOGGER.info(config.to_yaml)
         |