formatron 0.1.0

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.
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