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,16 @@
1
+ class Formatron
2
+ module Generators
3
+ module Util
4
+ # generates placeholder README.md
5
+ module Gitignore
6
+ def self.write(directory)
7
+ FileUtils.mkdir_p directory
8
+ readme = File.join directory, '.gitignore'
9
+ File.write readme, <<-EOH.gsub(/^ {12}/, '')
10
+ /.formatron/
11
+ EOH
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ class Formatron
2
+ module Generators
3
+ module Util
4
+ # generates placeholder README.md
5
+ module Readme
6
+ def self.write(directory, name)
7
+ FileUtils.mkdir_p directory
8
+ readme = File.join directory, 'README.md'
9
+ File.write readme, <<-EOH.gsub(/^ {12}/, '')
10
+ # #{name}
11
+
12
+ Formatron configuration
13
+ EOH
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ require 'logger'
2
+
3
+ # add logger to class
4
+ class Formatron
5
+ LOG = Logger.new($stdout).tap do |log|
6
+ log.progname = 'Formatron'
7
+ end
8
+ end
@@ -0,0 +1,85 @@
1
+ require_relative 'path'
2
+ require 'formatron/logger'
3
+
4
+ class Formatron
5
+ module S3
6
+ # manage the Chef Server SSL certificate and key stored on S3
7
+ module ChefServerCert
8
+ CERT_NAME = 'ssl.cert'
9
+ KEY_NAME = 'ssl.key'
10
+
11
+ # rubocop:disable Metrics/ParameterLists
12
+ # rubocop:disable Metrics/MethodLength
13
+ def self.deploy(
14
+ aws:,
15
+ kms_key:,
16
+ bucket:,
17
+ name:,
18
+ target:,
19
+ guid:,
20
+ cert:,
21
+ key:
22
+ )
23
+ cert_key = self.cert_key name: name, target: target, guid: guid
24
+ Formatron::LOG.info do
25
+ "Upload Chef Server SSL certifcate to #{bucket}/#{cert_key}"
26
+ end
27
+ aws.upload_file(
28
+ kms_key: kms_key,
29
+ bucket: bucket,
30
+ key: cert_key,
31
+ content: cert
32
+ )
33
+ key_key = self.key_key name: name, target: target, guid: guid
34
+ Formatron::LOG.info do
35
+ "Upload Chef Server SSL key to #{bucket}/#{key_key}"
36
+ end
37
+ aws.upload_file(
38
+ kms_key: kms_key,
39
+ bucket: bucket,
40
+ key: key_key,
41
+ content: key
42
+ )
43
+ end
44
+ # rubocop:enable Metrics/MethodLength
45
+ # rubocop:enable Metrics/ParameterLists
46
+
47
+ # rubocop:disable Metrics/MethodLength
48
+ def self.destroy(aws:, bucket:, name:, target:, guid:)
49
+ cert_key = self.cert_key name: name, target: target, guid: guid
50
+ Formatron::LOG.info do
51
+ "Delete Chef Server SSL certificate from #{bucket}/#{cert_key}"
52
+ end
53
+ aws.delete_file(
54
+ bucket: bucket,
55
+ key: cert_key
56
+ )
57
+ key_key = self.key_key name: name, target: target, guid: guid
58
+ Formatron::LOG.info do
59
+ "Delete Chef Server SSL key from #{bucket}/#{key_key}"
60
+ end
61
+ aws.delete_file(
62
+ bucket: bucket,
63
+ key: key_key
64
+ )
65
+ end
66
+ # rubocop:enable Metrics/MethodLength
67
+
68
+ def self.cert_key(name:, target:, guid:)
69
+ Path.key(
70
+ name: name,
71
+ target: target,
72
+ sub_key: "#{guid}/#{CERT_NAME}"
73
+ )
74
+ end
75
+
76
+ def self.key_key(name:, target:, guid:)
77
+ Path.key(
78
+ name: name,
79
+ target: target,
80
+ sub_key: "#{guid}/#{KEY_NAME}"
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,103 @@
1
+ require_relative 'path'
2
+ require 'formatron/logger'
3
+
4
+ class Formatron
5
+ module S3
6
+ # manage the Chef Server user and organization keys
7
+ module ChefServerKeys
8
+ USER_PEM_NAME = 'user.pem'
9
+ ORGANIZATION_PEM_NAME = 'organization.pem'
10
+
11
+ # rubocop:disable Metrics/MethodLength
12
+ # rubocop:disable Metrics/ParameterLists
13
+ def self.get(
14
+ aws:,
15
+ bucket:,
16
+ name:,
17
+ target:,
18
+ guid:,
19
+ directory:
20
+ )
21
+ user_pem_key = self.user_pem_key name: name, target: target, guid: guid
22
+ Formatron::LOG.info do
23
+ 'Download Chef Server user key from ' \
24
+ "#{bucket}/#{user_pem_key}"
25
+ end
26
+ aws.download_file(
27
+ bucket: bucket,
28
+ key: user_pem_key,
29
+ path: user_pem_path(directory: directory)
30
+ )
31
+ organization_pem_key = self.organization_pem_key(
32
+ name: name, target: target, guid: guid
33
+ )
34
+ Formatron::LOG.info do
35
+ 'Download Chef Server organization key ' \
36
+ "from #{bucket}/#{organization_pem_key}"
37
+ end
38
+ aws.download_file(
39
+ bucket: bucket,
40
+ key: organization_pem_key,
41
+ path: organization_pem_path(directory: directory)
42
+ )
43
+ end
44
+ # rubocop:enable Metrics/ParameterLists
45
+ # rubocop:enable Metrics/MethodLength
46
+
47
+ # rubocop:disable Metrics/MethodLength
48
+ def self.destroy(
49
+ aws:,
50
+ bucket:,
51
+ name:,
52
+ target:,
53
+ guid:
54
+ )
55
+ user_pem_key = self.user_pem_key name: name, target: target, guid: guid
56
+ Formatron::LOG.info do
57
+ 'Delete Chef Server user key from ' \
58
+ "#{bucket}/#{user_pem_key}"
59
+ end
60
+ aws.delete_file(
61
+ bucket: bucket,
62
+ key: user_pem_key
63
+ )
64
+ organization_pem_key = self.organization_pem_key(
65
+ name: name, target: target, guid: guid
66
+ )
67
+ Formatron::LOG.info do
68
+ 'Delete Chef Server organization key ' \
69
+ "from #{bucket}/#{organization_pem_key}"
70
+ end
71
+ aws.delete_file(
72
+ bucket: bucket,
73
+ key: organization_pem_key
74
+ )
75
+ end
76
+ # rubocop:enable Metrics/MethodLength
77
+
78
+ def self.user_pem_key(name:, target:, guid:)
79
+ Path.key(
80
+ name: name,
81
+ target: target,
82
+ sub_key: "#{guid}/#{USER_PEM_NAME}"
83
+ )
84
+ end
85
+
86
+ def self.user_pem_path(directory:)
87
+ File.join directory, USER_PEM_NAME
88
+ end
89
+
90
+ def self.organization_pem_key(name:, target:, guid:)
91
+ Path.key(
92
+ name: name,
93
+ target: target,
94
+ sub_key: "#{guid}/#{ORGANIZATION_PEM_NAME}"
95
+ )
96
+ end
97
+
98
+ def self.organization_pem_path(directory:)
99
+ File.join directory, ORGANIZATION_PEM_NAME
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,61 @@
1
+ require_relative 'path'
2
+ require 'formatron/logger'
3
+
4
+ class Formatron
5
+ module S3
6
+ # manage the CloudFormation template stored on S3
7
+ module CloudFormationTemplate
8
+ FILE_NAME = 'cloud_formation_template.json'
9
+
10
+ # rubocop:disable Metrics/ParameterLists
11
+ # rubocop:disable Metrics/MethodLength
12
+ def self.deploy(
13
+ aws:, kms_key:, bucket:, name:, target:, cloud_formation_template:
14
+ )
15
+ key = Path.key(
16
+ name: name,
17
+ target: target,
18
+ sub_key: FILE_NAME
19
+ )
20
+ Formatron::LOG.info do
21
+ "Upload CloudFormation template to #{bucket}/#{key}"
22
+ end
23
+ aws.upload_file(
24
+ kms_key: kms_key,
25
+ bucket: bucket,
26
+ key: key,
27
+ content: cloud_formation_template
28
+ )
29
+ end
30
+ # rubocop:enable Metrics/MethodLength
31
+ # rubocop:enable Metrics/ParameterLists
32
+
33
+ # rubocop:disable Metrics/MethodLength
34
+ def self.destroy(aws:, bucket:, name:, target:)
35
+ key = Path.key(
36
+ name: name,
37
+ target: target,
38
+ sub_key: FILE_NAME
39
+ )
40
+ Formatron::LOG.info do
41
+ "Delete CloudFormation template from #{bucket}/#{key}"
42
+ end
43
+ aws.delete_file(
44
+ bucket: bucket,
45
+ key: key
46
+ )
47
+ end
48
+ # rubocop:enable Metrics/MethodLength
49
+
50
+ def self.url(region:, bucket:, name:, target:)
51
+ Path.url(
52
+ region: region,
53
+ bucket: bucket,
54
+ name: name,
55
+ target: target,
56
+ sub_key: FILE_NAME
57
+ )
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,58 @@
1
+ require_relative 'path'
2
+ require 'formatron/logger'
3
+
4
+ class Formatron
5
+ module S3
6
+ # manage the configuration stored on S3
7
+ module Configuration
8
+ FILE_NAME = 'configuration.json'
9
+
10
+ # rubocop:disable Metrics/ParameterLists
11
+ def self.deploy(aws:, kms_key:, bucket:, name:, target:, configuration:)
12
+ key = self.key name: name, target: target
13
+ Formatron::LOG.info do
14
+ "Upload configuration to #{bucket}/#{key}"
15
+ end
16
+ aws.upload_file(
17
+ kms_key: kms_key,
18
+ bucket: bucket,
19
+ key: key,
20
+ content: "#{JSON.pretty_generate(configuration)}\n"
21
+ )
22
+ end
23
+ # rubocop:enable Metrics/ParameterLists
24
+
25
+ def self.get(aws:, bucket:, name:, target:)
26
+ key = self.key name: name, target: target
27
+ Formatron::LOG.info do
28
+ "Get configuration from #{bucket}/#{key}"
29
+ end
30
+ JSON.parse(
31
+ aws.get_file(
32
+ bucket: bucket,
33
+ key: key
34
+ )
35
+ )
36
+ end
37
+
38
+ def self.destroy(aws:, bucket:, name:, target:)
39
+ key = self.key name: name, target: target
40
+ Formatron::LOG.info do
41
+ "Delete configuration from #{bucket}/#{key}"
42
+ end
43
+ aws.delete_file(
44
+ bucket: bucket,
45
+ key: key
46
+ )
47
+ end
48
+
49
+ def self.key(name:, target:)
50
+ Path.key(
51
+ name: name,
52
+ target: target,
53
+ sub_key: FILE_NAME
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ class Formatron
2
+ module S3
3
+ # defines the S3 bucket keys for consistency
4
+ module Path
5
+ def self.key(name:, target:, sub_key:)
6
+ File.join _base_path(
7
+ name: name,
8
+ target: target
9
+ ), sub_key
10
+ end
11
+
12
+ def self.url(region:, bucket:, name:, target:, sub_key:)
13
+ key = key(
14
+ name: name,
15
+ target: target,
16
+ sub_key: sub_key
17
+ )
18
+ "https://s3-#{region}.amazonaws.com/#{bucket}/#{key}"
19
+ end
20
+
21
+ def self._base_path(name:, target:)
22
+ File.join target, name
23
+ end
24
+
25
+ private_class_method(
26
+ :_base_path
27
+ )
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,107 @@
1
+ class Formatron
2
+ module Util
3
+ # utilities for generating DSL classes
4
+ module DSL
5
+ def dsl_initialize_block(&block)
6
+ define_method :initialize do |**params|
7
+ instance_exec(**params, &block) unless block.nil?
8
+ end
9
+ end
10
+
11
+ def dsl_initialize_hash(&block)
12
+ define_method :initialize do |dsl_key, **params|
13
+ instance_exec(
14
+ dsl_key,
15
+ **params,
16
+ &block
17
+ ) unless block.nil?
18
+ end
19
+ end
20
+
21
+ def dsl_property(symbol)
22
+ iv = "@#{symbol}"
23
+ define_method symbol do |value = nil|
24
+ instance_variable_set iv, value unless value.nil?
25
+ instance_variable_get iv
26
+ end
27
+ end
28
+
29
+ # rubocop:disable Metrics/MethodLength
30
+ def dsl_block(symbol, cls, &params_block)
31
+ iv = "@#{symbol}"
32
+ define_method symbol do |&block|
33
+ value = instance_variable_get(iv)
34
+ if value.nil?
35
+ params = {}
36
+ params = instance_eval(
37
+ &params_block
38
+ ) unless params_block.nil?
39
+ value = self.class.const_get(cls).new(**params)
40
+ instance_variable_set iv, value
41
+ end
42
+ block.call value unless block.nil?
43
+ instance_variable_get iv
44
+ end
45
+ end
46
+ # rubocop:enable Metrics/MethodLength
47
+
48
+ # rubocop:disable Metrics/MethodLength
49
+ def dsl_hash(symbol, cls, &params_block)
50
+ iv = "@#{symbol}"
51
+ define_method symbol do |dsl_key = nil, &block|
52
+ hash = instance_variable_get(iv)
53
+ if hash.nil?
54
+ hash = {}
55
+ instance_variable_set iv, hash
56
+ end
57
+ unless dsl_key.nil?
58
+ params = {}
59
+ params = instance_exec(
60
+ dsl_key, &params_block
61
+ ) unless params_block.nil?
62
+ value = self.class.const_get(cls).new(
63
+ dsl_key,
64
+ **params
65
+ )
66
+ hash[dsl_key] = value
67
+ block.call value unless block.nil?
68
+ end
69
+ hash
70
+ end
71
+ end
72
+ # rubocop:enable Metrics/MethodLength
73
+
74
+ def dsl_array(symbol)
75
+ iv = "@#{symbol}"
76
+ define_method symbol do |value = nil|
77
+ array = instance_variable_get(iv)
78
+ if array.nil?
79
+ array = []
80
+ instance_variable_set iv, array
81
+ end
82
+ array.push value unless value.nil?
83
+ array
84
+ end
85
+ end
86
+
87
+ # rubocop:disable Metrics/MethodLength
88
+ def dsl_block_array(symbol, cls)
89
+ iv = "@#{symbol}"
90
+ define_method symbol do |&block|
91
+ array = instance_variable_get(iv)
92
+ if array.nil?
93
+ array = []
94
+ instance_variable_set iv, array
95
+ end
96
+ unless block.nil?
97
+ value = self.class.const_get(cls).new
98
+ array.push value
99
+ block.call value
100
+ end
101
+ array
102
+ end
103
+ end
104
+ # rubocop:enable Metrics/MethodLength
105
+ end
106
+ end
107
+ end