formatron 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +3 -0
  6. data/.simplecov +7 -0
  7. data/.travis.yml +17 -0
  8. data/CODE_OF_CONDUCT.md +13 -0
  9. data/Gemfile +6 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +93 -0
  13. data/Rakefile +16 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +7 -0
  16. data/exe/formatron +20 -0
  17. data/formatron.gemspec +52 -0
  18. data/lib/formatron.rb +357 -0
  19. data/lib/formatron/aws.rb +197 -0
  20. data/lib/formatron/chef.rb +156 -0
  21. data/lib/formatron/chef/berkshelf.rb +55 -0
  22. data/lib/formatron/chef/keys.rb +48 -0
  23. data/lib/formatron/chef/knife.rb +169 -0
  24. data/lib/formatron/chef_clients.rb +73 -0
  25. data/lib/formatron/cli.rb +33 -0
  26. data/lib/formatron/cli/completion.rb +26 -0
  27. data/lib/formatron/cli/deploy.rb +57 -0
  28. data/lib/formatron/cli/destroy.rb +57 -0
  29. data/lib/formatron/cli/generators/bootstrap.rb +250 -0
  30. data/lib/formatron/cli/generators/credentials.rb +100 -0
  31. data/lib/formatron/cli/generators/instance.rb +118 -0
  32. data/lib/formatron/cli/provision.rb +59 -0
  33. data/lib/formatron/cloud_formation.rb +54 -0
  34. data/lib/formatron/cloud_formation/resources/cloud_formation.rb +27 -0
  35. data/lib/formatron/cloud_formation/resources/ec2.rb +336 -0
  36. data/lib/formatron/cloud_formation/resources/iam.rb +94 -0
  37. data/lib/formatron/cloud_formation/resources/route53.rb +54 -0
  38. data/lib/formatron/cloud_formation/scripts.rb +128 -0
  39. data/lib/formatron/cloud_formation/template.rb +114 -0
  40. data/lib/formatron/cloud_formation/template/parameters.rb +20 -0
  41. data/lib/formatron/cloud_formation/template/vpc.rb +181 -0
  42. data/lib/formatron/cloud_formation/template/vpc/subnet.rb +187 -0
  43. data/lib/formatron/cloud_formation/template/vpc/subnet/acl.rb +147 -0
  44. data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +66 -0
  45. data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +205 -0
  46. data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +162 -0
  47. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/policy.rb +74 -0
  48. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +117 -0
  49. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +68 -0
  50. data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +94 -0
  51. data/lib/formatron/completion.rb +26 -0
  52. data/lib/formatron/completion/completion.sh.erb +35 -0
  53. data/lib/formatron/config.rb +31 -0
  54. data/lib/formatron/config/reader.rb +29 -0
  55. data/lib/formatron/dsl.rb +15 -0
  56. data/lib/formatron/dsl/formatron.rb +25 -0
  57. data/lib/formatron/dsl/formatron/global.rb +19 -0
  58. data/lib/formatron/dsl/formatron/global/ec2.rb +17 -0
  59. data/lib/formatron/dsl/formatron/vpc.rb +17 -0
  60. data/lib/formatron/dsl/formatron/vpc/subnet.rb +27 -0
  61. data/lib/formatron/dsl/formatron/vpc/subnet/acl.rb +18 -0
  62. data/lib/formatron/dsl/formatron/vpc/subnet/chef_server.rb +32 -0
  63. data/lib/formatron/dsl/formatron/vpc/subnet/chef_server/organization.rb +22 -0
  64. data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +29 -0
  65. data/lib/formatron/dsl/formatron/vpc/subnet/instance/chef.rb +22 -0
  66. data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy.rb +21 -0
  67. data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy/statement.rb +23 -0
  68. data/lib/formatron/dsl/formatron/vpc/subnet/instance/security_group.rb +21 -0
  69. data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup.rb +22 -0
  70. data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup/variable.rb +23 -0
  71. data/lib/formatron/external.rb +61 -0
  72. data/lib/formatron/external/dsl.rb +171 -0
  73. data/lib/formatron/external/outputs.rb +25 -0
  74. data/lib/formatron/generators/bootstrap.rb +90 -0
  75. data/lib/formatron/generators/bootstrap/config.rb +62 -0
  76. data/lib/formatron/generators/bootstrap/ec2.rb +17 -0
  77. data/lib/formatron/generators/bootstrap/formatronfile.rb +52 -0
  78. data/lib/formatron/generators/bootstrap/formatronfile/Formatronfile.erb +79 -0
  79. data/lib/formatron/generators/bootstrap/ssl.rb +35 -0
  80. data/lib/formatron/generators/credentials.rb +17 -0
  81. data/lib/formatron/generators/instance.rb +64 -0
  82. data/lib/formatron/generators/instance/config.rb +47 -0
  83. data/lib/formatron/generators/instance/formatronfile.rb +47 -0
  84. data/lib/formatron/generators/instance/formatronfile/Formatronfile.erb +16 -0
  85. data/lib/formatron/generators/util.rb +14 -0
  86. data/lib/formatron/generators/util/cookbook.rb +65 -0
  87. data/lib/formatron/generators/util/gitignore.rb +16 -0
  88. data/lib/formatron/generators/util/readme.rb +18 -0
  89. data/lib/formatron/logger.rb +8 -0
  90. data/lib/formatron/s3/chef_server_cert.rb +85 -0
  91. data/lib/formatron/s3/chef_server_keys.rb +103 -0
  92. data/lib/formatron/s3/cloud_formation_template.rb +61 -0
  93. data/lib/formatron/s3/configuration.rb +58 -0
  94. data/lib/formatron/s3/path.rb +30 -0
  95. data/lib/formatron/util/dsl.rb +107 -0
  96. data/lib/formatron/util/shell.rb +20 -0
  97. data/lib/formatron/util/vpc.rb +15 -0
  98. data/lib/formatron/version.rb +4 -0
  99. data/support/cloudformation_describe_stacks_response.rb +36 -0
  100. data/support/dsl_test.rb +123 -0
  101. data/support/route53_get_hosted_zone_response.rb +21 -0
  102. data/support/s3_get_object_response.rb +21 -0
  103. data/support/template_test.rb +41 -0
  104. metadata +414 -0
@@ -0,0 +1,17 @@
1
+ class Formatron
2
+ module Generators
3
+ module Bootstrap
4
+ # generates placeholder README.md
5
+ module EC2
6
+ def self.write(directory)
7
+ ec2_directory = File.join directory, 'config/_default/ec2'
8
+ FileUtils.mkdir_p ec2_directory
9
+ private_key = File.join ec2_directory, 'private_key'
10
+ File.write private_key, <<-EOH.gsub(/^ {12}/, '')
11
+ Remember to replace this file with the EC2 private key
12
+ EOH
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ require 'erb'
2
+ require 'curb'
3
+ require 'formatron/generators/util'
4
+
5
+ class Formatron
6
+ module Generators
7
+ module Bootstrap
8
+ # generates a bootstrap Formatronfile
9
+ module Formatronfile
10
+ # exports params to bootstrap ERB template
11
+ class Template
12
+ attr_reader :params, :ip
13
+
14
+ def initialize(params)
15
+ @params = params
16
+ @ip = Curl.get('http://whatismyip.akamai.com').body_str
17
+ end
18
+
19
+ def guid
20
+ Util.guid
21
+ end
22
+
23
+ def databag_secret
24
+ Util.databag_secret
25
+ end
26
+ end
27
+
28
+ def self.write(directory, params)
29
+ FileUtils.mkdir_p directory
30
+ formatronfile = File.join directory, 'Formatronfile'
31
+ File.write formatronfile, _content(params)
32
+ end
33
+
34
+ def self._content(params)
35
+ template = File.join(
36
+ File.dirname(File.expand_path(__FILE__)),
37
+ File.basename(__FILE__, '.rb'),
38
+ 'Formatronfile.erb'
39
+ )
40
+ erb = ERB.new File.read(template)
41
+ erb.filename = template
42
+ erb_template = erb.def_class Template, 'render()'
43
+ erb_template.new(params).render
44
+ end
45
+
46
+ private_class_method(
47
+ :_content
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,79 @@
1
+ formatron.name '<%= params[:name] %>'
2
+ formatron.bucket '<%= params[:s3_bucket] %>'
3
+
4
+ formatron.global do |global|
5
+ global.protect config['protected']
6
+ global.kms_key '<%= params[:kms_key] %>'
7
+ global.databag_secret '<%= databag_secret %>'
8
+ global.hosted_zone_id '<%= params[:hosted_zone_id] %>'
9
+
10
+ global.ec2 do |ec2|
11
+ ec2.key_pair '<%= params[:ec2_key_pair] %>'
12
+ ec2.private_key config['ec2']['private_key']
13
+ end
14
+ end
15
+
16
+ formatron.vpc 'vpc' do |vpc|
17
+ vpc.guid 'VPC<%= guid %>'
18
+ vpc.cidr '10.0.0.0/16'
19
+
20
+ vpc.subnet 'management' do |subnet|
21
+ subnet.guid 'SUBNET<%= guid %>'
22
+ subnet.availability_zone '<%= params[:availability_zone] %>'
23
+ subnet.cidr '10.0.0.0/24'
24
+ subnet.acl do |acl|
25
+ acl.source_cidr '<%= ip %>/32'
26
+ end
27
+
28
+ subnet.bastion 'bastion' do |bastion|
29
+ bastion.guid 'BASTION<%= guid %>'
30
+ bastion.sub_domain config['bastion']['sub_domain']
31
+ bastion.chef do |chef|
32
+ chef.cookbook 'cookbooks/bastion_instance'
33
+ end
34
+ end
35
+
36
+ subnet.nat 'nat' do |nat|
37
+ nat.guid 'NAT<%= guid %>'
38
+ nat.sub_domain config['nat']['sub_domain']
39
+ nat.chef do |chef|
40
+ chef.cookbook 'cookbooks/nat_instance'
41
+ end
42
+ end
43
+
44
+ subnet.chef_server 'chef_server' do |chef_server|
45
+ chef_server.guid 'CHEF<%= guid %>'
46
+ chef_server.version '12.2.0-1'
47
+ chef_server.sub_domain config['chef_server']['sub_domain']
48
+ chef_server.cookbooks_bucket config['chef_server']['cookbooks_bucket']
49
+ chef_server.organization do |organization|
50
+ organization.short_name '<%= params[:chef_server][:organization][:short_name] %>'
51
+ organization.full_name '<%= params[:chef_server][:organization][:full_name] %>'
52
+ end
53
+ chef_server.username '<%= params[:chef_server][:username] %>'
54
+ chef_server.email '<%= params[:chef_server][:email] %>'
55
+ chef_server.first_name '<%= params[:chef_server][:first_name] %>'
56
+ chef_server.last_name '<%= params[:chef_server][:last_name] %>'
57
+ chef_server.password '<%= params[:chef_server][:password] %>'
58
+ chef_server.ssl_key config['chef_server']['ssl']['key']
59
+ chef_server.ssl_cert config['chef_server']['ssl']['cert']
60
+ chef_server.ssl_verify config['chef_server']['ssl']['verify']
61
+ chef_server.chef do |chef|
62
+ chef.cookbook 'cookbooks/chef_server_instance'
63
+ end
64
+ end
65
+ end
66
+
67
+ vpc.subnet 'public' do |subnet|
68
+ subnet.guid 'SUBNET<%= guid %>'
69
+ subnet.availability_zone '<%= params[:availability_zone] %>'
70
+ subnet.cidr '10.0.1.0/24'
71
+ end
72
+
73
+ vpc.subnet 'private' do |subnet|
74
+ subnet.guid 'SUBNET<%= guid %>'
75
+ subnet.availability_zone '<%= params[:availability_zone] %>'
76
+ subnet.cidr '10.0.2.0/24'
77
+ subnet.gateway 'nat'
78
+ end
79
+ end
@@ -0,0 +1,35 @@
1
+ class Formatron
2
+ module Generators
3
+ module Bootstrap
4
+ # generates placeholder SSL stuff
5
+ module SSL
6
+ def self.write_key(directory)
7
+ placeholder_key = File.join directory, 'key'
8
+ File.write placeholder_key, <<-EOH.gsub(/^ {12}/, '')
9
+ Remember to generate an SSL key
10
+ EOH
11
+ end
12
+
13
+ def self.write_cert(directory)
14
+ placeholder_cert = File.join directory, 'cert'
15
+ File.write placeholder_cert, <<-EOH.gsub(/^ {12}/, '')
16
+ Remember to generate an SSL certificate
17
+ EOH
18
+ end
19
+
20
+ def self.write(directory, target)
21
+ target_directory = File.join(
22
+ directory,
23
+ 'config',
24
+ target.to_s,
25
+ 'chef_server',
26
+ 'ssl'
27
+ )
28
+ FileUtils.mkdir_p target_directory
29
+ write_key target_directory
30
+ write_cert target_directory
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ class Formatron
2
+ module Generators
3
+ # generates a credentials JSON file
4
+ module Credentials
5
+ def self.generate(file, region, access_key_id, secret_access_key)
6
+ FileUtils.mkdir_p File.dirname(file)
7
+ File.write file, <<-EOH.gsub(/^ {10}/, '')
8
+ {
9
+ "region": "#{region}",
10
+ "access_key_id": "#{access_key_id}",
11
+ "secret_access_key": "#{secret_access_key}"
12
+ }
13
+ EOH
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'instance/formatronfile'
2
+ require_relative 'instance/config'
3
+ require_relative 'util/cookbook'
4
+ require_relative 'util/readme'
5
+ require_relative 'util/gitignore'
6
+
7
+ class Formatron
8
+ module Generators
9
+ # generates an instance configuration
10
+ module Instance
11
+ def self.validate_hash_params(hash, params)
12
+ params.each do |param|
13
+ fail "params should contain #{param}" if hash[param].nil?
14
+ end
15
+ end
16
+
17
+ def self.validate_params(params)
18
+ validate_hash_params params, [
19
+ :name,
20
+ :instance_name,
21
+ :s3_bucket,
22
+ :bootstrap_configuration,
23
+ :vpc,
24
+ :subnet,
25
+ :targets
26
+ ]
27
+ end
28
+
29
+ def self.generate_targets(directory, targets, name)
30
+ targets.each do |target|
31
+ Config.write(
32
+ directory,
33
+ target,
34
+ name
35
+ )
36
+ end
37
+ end
38
+
39
+ def self.generate_cookbooks(directory, name)
40
+ Util::Cookbook.write(
41
+ directory,
42
+ "#{name}_instance",
43
+ "#{name} instance"
44
+ )
45
+ end
46
+
47
+ # rubocop:disable Metrics/MethodLength
48
+ def self.generate(directory, params)
49
+ validate_params params
50
+ Util::Readme.write directory, params[:name]
51
+ Util::Gitignore.write directory
52
+ Formatronfile.write directory, params
53
+ Config.write directory
54
+ generate_targets(
55
+ directory,
56
+ params[:targets],
57
+ params[:instance_name]
58
+ )
59
+ generate_cookbooks directory, params[:instance_name]
60
+ end
61
+ # rubocop:enable Metrics/MethodLength
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,47 @@
1
+ class Formatron
2
+ module Generators
3
+ module Instance
4
+ # generates an empty config
5
+ module Config
6
+ def self.write_default(file)
7
+ File.write file, <<-EOH.gsub(/^ {12}/, '')
8
+ {
9
+ }
10
+ EOH
11
+ end
12
+
13
+ def self.write_target(file, target, name)
14
+ File.write file, <<-EOH.gsub(/^ {12}/, '')
15
+ {
16
+ "#{name}": {
17
+ "sub_domain": "#{name}-#{target}"
18
+ }
19
+ }
20
+ EOH
21
+ end
22
+
23
+ # rubocop:disable Metrics/MethodLength
24
+ def self.write(
25
+ directory,
26
+ target = nil,
27
+ name = nil
28
+ )
29
+ target_directory = File.join(
30
+ directory,
31
+ 'config',
32
+ target.nil? ? '_default' : target.to_s
33
+ )
34
+ FileUtils.mkdir_p target_directory
35
+ file = File.join target_directory, '_default.json'
36
+ write_default(file) if target.nil?
37
+ write_target(
38
+ file,
39
+ target,
40
+ name
41
+ ) unless target.nil?
42
+ end
43
+ # rubocop:enable Metrics/MethodLength
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require 'erb'
2
+ require 'curb'
3
+ require 'formatron/generators/util'
4
+
5
+ class Formatron
6
+ module Generators
7
+ module Instance
8
+ # generates a bootstrap Formatronfile
9
+ module Formatronfile
10
+ # exports params to bootstrap ERB template
11
+ class Template
12
+ attr_reader :params
13
+
14
+ def initialize(params)
15
+ @params = params
16
+ end
17
+
18
+ def guid
19
+ Util.guid
20
+ end
21
+ end
22
+
23
+ def self.write(directory, params)
24
+ FileUtils.mkdir_p directory
25
+ formatronfile = File.join directory, 'Formatronfile'
26
+ File.write formatronfile, _content(params)
27
+ end
28
+
29
+ def self._content(params)
30
+ template = File.join(
31
+ File.dirname(File.expand_path(__FILE__)),
32
+ File.basename(__FILE__, '.rb'),
33
+ 'Formatronfile.erb'
34
+ )
35
+ erb = ERB.new File.read(template)
36
+ erb.filename = template
37
+ erb_template = erb.def_class Template, 'render()'
38
+ erb_template.new(params).render
39
+ end
40
+
41
+ private_class_method(
42
+ :_content
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,16 @@
1
+ formatron.name '<%= params[:name] %>'
2
+ formatron.bucket '<%= params[:s3_bucket] %>'
3
+
4
+ formatron.depends '<%= params[:bootstrap_configuration] %>'
5
+
6
+ formatron.vpc '<%= params[:vpc] %>' do |vpc|
7
+ vpc.subnet '<%= params[:subnet] %>' do |subnet|
8
+ subnet.instance '<%= params[:instance_name] %>' do |instance|
9
+ instance.guid 'INSTANCE<%= guid %>'
10
+ instance.sub_domain config['<%= params[:instance_name] %>']['sub_domain']
11
+ instance.chef do |chef|
12
+ chef.cookbook 'cookbooks/<%= params[:instance_name] %>_instance'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ class Formatron
2
+ module Generators
3
+ # Utility methods
4
+ module Util
5
+ def self.guid
6
+ Random.rand(36**8).to_s(36).upcase
7
+ end
8
+
9
+ def self.databag_secret
10
+ Random.rand(36**40).to_s(36).upcase
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+ class Formatron
2
+ module Generators
3
+ module Util
4
+ # generates placeholder cookbooks
5
+ module Cookbook
6
+ def self.write(directory, name, description)
7
+ cookbook_directory = File.join(
8
+ directory,
9
+ 'cookbooks',
10
+ name
11
+ )
12
+ _write_cookbook_metadata cookbook_directory, name
13
+ _write_cookbook_readme cookbook_directory, name, description
14
+ _write_cookbook_berksfile cookbook_directory
15
+ _write_cookbook_recipe cookbook_directory
16
+ end
17
+
18
+ def self._write_cookbook_metadata(directory, name)
19
+ FileUtils.mkdir_p directory
20
+ metadata = File.join directory, 'metadata.rb'
21
+ File.write metadata, <<-EOH.gsub(/^ {12}/, '')
22
+ name '#{name}'
23
+ version '0.1.0'
24
+ supports 'ubuntu'
25
+ EOH
26
+ end
27
+
28
+ def self._write_cookbook_readme(directory, name, description)
29
+ FileUtils.mkdir_p directory
30
+ readme = File.join directory, 'README.md'
31
+ File.write readme, <<-EOH.gsub(/^ {12}/, '')
32
+ # #{name}
33
+
34
+ Cookbook to perform additional configuration on the #{description}
35
+ EOH
36
+ end
37
+
38
+ def self._write_cookbook_berksfile(directory)
39
+ FileUtils.mkdir_p directory
40
+ berksfile = File.join directory, 'Berksfile'
41
+ File.write berksfile, <<-EOH.gsub(/^ {12}/, '')
42
+ source 'https://supermarket.chef.io'
43
+
44
+ metadata
45
+ EOH
46
+ end
47
+
48
+ def self._write_cookbook_recipe(directory)
49
+ recipes_directory = File.join directory, 'recipes'
50
+ FileUtils.mkdir_p recipes_directory
51
+ recipe = File.join recipes_directory, 'default.rb'
52
+ File.write recipe, <<-EOH.gsub(/^ {12}/, '')
53
+ EOH
54
+ end
55
+
56
+ private_class_method(
57
+ :_write_cookbook_metadata,
58
+ :_write_cookbook_readme,
59
+ :_write_cookbook_berksfile,
60
+ :_write_cookbook_recipe
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end