formatron 0.1.14 → 0.1.15
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 +4 -4
- data/formatron.gemspec +2 -1
- data/lib/formatron.rb +23 -10
- data/lib/formatron/aws.rb +26 -13
- data/lib/formatron/chef.rb +53 -9
- data/lib/formatron/chef/berkshelf.rb +15 -11
- data/lib/formatron/chef/keys.rb +5 -9
- data/lib/formatron/chef/knife.rb +39 -30
- data/lib/formatron/chef/ssh.rb +4 -1
- data/lib/formatron/chef/winrm.rb +37 -0
- data/lib/formatron/chef_clients.rb +6 -4
- data/lib/formatron/cli/generators/credentials.rb +1 -1
- data/lib/formatron/cloud_formation/resources/ec2.rb +58 -57
- data/lib/formatron/cloud_formation/scripts.rb +75 -3
- data/lib/formatron/cloud_formation/template.rb +6 -0
- data/lib/formatron/cloud_formation/template/vpc.rb +8 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet.rb +8 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +12 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +12 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +13 -2
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +47 -2
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +92 -27
- data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +12 -0
- data/lib/formatron/dsl/formatron/global.rb +2 -0
- data/lib/formatron/dsl/formatron/global/windows.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +1 -0
- data/lib/formatron/external/dsl.rb +19 -0
- data/lib/formatron/util/winrm.rb +40 -0
- data/lib/formatron/version.rb +1 -1
- metadata +33 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 932f38c884b67c73450aa6842772390de1db150f
|
4
|
+
data.tar.gz: 7e70e25c5de6024938501fc0935c33c392546bc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c1d72b86843a572767eadc0607cc3a8b8275d392b3ad73902186313c04809446dde1ba7bd13c2ea74b2f8b3a371014a2b95c1956a5e98da8b5fb099a7dca76e
|
7
|
+
data.tar.gz: 69abb715018d08008170e6192499695561dc8532c00dd5f2aed3283e989538aed49bd3d43d5fbaaa6f71087c20292fd6080d25f7b9185451d242424a3fb1c29d
|
data/formatron.gemspec
CHANGED
@@ -38,7 +38,6 @@ EOH
|
|
38
38
|
spec.add_development_dependency 'pry-remote', '~> 0.1'
|
39
39
|
spec.add_development_dependency 'pry-nav', '~> 0.2'
|
40
40
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
41
|
-
spec.add_development_dependency 'codacy-coverage', '~> 0.3'
|
42
41
|
spec.add_development_dependency 'rubocop', '0.33'
|
43
42
|
spec.add_development_dependency 'guard-livereload', '~> 2.4'
|
44
43
|
spec.add_development_dependency 'guard-rake', '~> 1.0'
|
@@ -50,5 +49,7 @@ EOH
|
|
50
49
|
spec.add_runtime_dependency 'deep_merge', '~> 1.0'
|
51
50
|
spec.add_runtime_dependency 'berkshelf', '~> 4.0'
|
52
51
|
spec.add_runtime_dependency 'chef', '~> 12.5'
|
52
|
+
spec.add_runtime_dependency 'knife-windows', '~> 1.3'
|
53
53
|
spec.add_runtime_dependency 'net-ssh', '~> 2.9'
|
54
|
+
spec.add_runtime_dependency 'winrm', '~> 1.7'
|
54
55
|
end
|
data/lib/formatron.rb
CHANGED
@@ -17,12 +17,14 @@ require 'formatron/external'
|
|
17
17
|
# rubocop:disable Metrics/ClassLength
|
18
18
|
class Formatron
|
19
19
|
FORMATRONFILE = 'Formatronfile'
|
20
|
+
WORKING_DIRECTORY = '.formatron'
|
20
21
|
|
21
22
|
attr_reader :protected
|
22
23
|
alias_method :protected?, :protected
|
23
24
|
|
24
25
|
# rubocop:disable Metrics/MethodLength
|
25
26
|
def initialize(credentials:, directory:, target:)
|
27
|
+
@working_directory = File.join directory, WORKING_DIRECTORY, target
|
26
28
|
@target = target
|
27
29
|
@aws = AWS.new credentials: credentials
|
28
30
|
@config = Config.target(
|
@@ -59,9 +61,17 @@ class Formatron
|
|
59
61
|
external_global = external_formatron.global
|
60
62
|
global = @formatron.global || external_global
|
61
63
|
external_ec2 = external_global.ec2
|
64
|
+
external_windows = external_global.windows
|
62
65
|
ec2 = global.ec2 || external_ec2
|
63
66
|
key_pair = ec2.key_pair || external_ec2.key_pair
|
64
67
|
@ec2_key = ec2.private_key || external_ec2.private_key
|
68
|
+
windows = global.windows || external_windows
|
69
|
+
@administrator_name =
|
70
|
+
windows.administrator_name ||
|
71
|
+
external_windows.administrator_name
|
72
|
+
@administrator_password =
|
73
|
+
windows.administrator_password ||
|
74
|
+
external_windows.administrator_password
|
65
75
|
@protected = global.protect || external_global.protect
|
66
76
|
@kms_key = global.kms_key || external_global.kms_key
|
67
77
|
@databag_secret = global.databag_secret || external_global.databag_secret
|
@@ -73,6 +83,8 @@ class Formatron
|
|
73
83
|
formatron: @formatron,
|
74
84
|
hosted_zone_name: @hosted_zone_name,
|
75
85
|
key_pair: key_pair,
|
86
|
+
administrator_name: @administrator_name,
|
87
|
+
administrator_password: @administrator_password,
|
76
88
|
kms_key: @kms_key,
|
77
89
|
hosted_zone_id: hosted_zone_id,
|
78
90
|
target: @target,
|
@@ -91,11 +103,14 @@ class Formatron
|
|
91
103
|
@chef_clients = {}
|
92
104
|
@vpcs.each do |key, vpc|
|
93
105
|
@chef_clients[key] = ChefClients.new(
|
106
|
+
directory: @working_directory,
|
94
107
|
aws: @aws,
|
95
108
|
bucket: @bucket,
|
96
109
|
name: @name,
|
97
110
|
target: @target,
|
98
111
|
ec2_key: @ec2_key,
|
112
|
+
administrator_name: @administrator_name,
|
113
|
+
administrator_password: @administrator_password,
|
99
114
|
hosted_zone_name: @hosted_zone_name,
|
100
115
|
vpc: vpc,
|
101
116
|
external: @external_vpcs[key],
|
@@ -160,29 +175,31 @@ class Formatron
|
|
160
175
|
chef_clients.init
|
161
176
|
instances.values.each do |instance|
|
162
177
|
guid = instance.guid
|
178
|
+
os = instance.os
|
163
179
|
next unless guid_filter.nil? || guid_filter.eql?(guid)
|
164
180
|
dsl_chef = instance.chef
|
165
|
-
next if dsl_chef.nil?
|
181
|
+
next if dsl_chef.cookbook.nil?
|
166
182
|
chef = chef_clients.get dsl_chef.server
|
167
183
|
cookbook = dsl_chef.cookbook
|
168
184
|
bastion = dsl_chef.bastion
|
169
185
|
sub_domain = instance.sub_domain
|
170
|
-
_provision_instance chef, cookbook, sub_domain, guid, bastion
|
186
|
+
_provision_instance chef, cookbook, sub_domain, guid, bastion, os
|
171
187
|
end
|
172
|
-
ensure
|
173
|
-
chef_clients.unlink
|
174
188
|
end
|
175
189
|
# rubocop:enable Metrics/AbcSize
|
176
190
|
# rubocop:enable Metrics/MethodLength
|
177
191
|
|
178
|
-
|
192
|
+
# rubocop:disable Metrics/ParameterLists
|
193
|
+
def _provision_instance(chef, cookbook, sub_domain, guid, bastion, os)
|
179
194
|
chef.provision(
|
195
|
+
os: os,
|
180
196
|
sub_domain: sub_domain,
|
181
197
|
guid: guid,
|
182
198
|
cookbook: cookbook,
|
183
199
|
bastion: bastion
|
184
200
|
)
|
185
201
|
end
|
202
|
+
# rubocop:enable Metrics/ParameterLists
|
186
203
|
|
187
204
|
def destroy
|
188
205
|
_destroy_chef_instances
|
@@ -319,21 +336,17 @@ class Formatron
|
|
319
336
|
end
|
320
337
|
end
|
321
338
|
|
322
|
-
# rubocop:disable Metrics/MethodLength
|
323
339
|
def _destroy_chef_vpc_instances(key, instances)
|
324
340
|
chef_clients = @chef_clients[key]
|
325
341
|
chef_clients.init
|
326
342
|
instances.values.each do |instance|
|
327
343
|
dsl_chef = instance.chef
|
328
|
-
next if dsl_chef.nil?
|
344
|
+
next if dsl_chef.cookbook.nil?
|
329
345
|
chef = chef_clients.get dsl_chef.server
|
330
346
|
guid = instance.guid
|
331
347
|
_destroy_chef_instance chef, guid
|
332
348
|
end
|
333
|
-
ensure
|
334
|
-
chef_clients.unlink
|
335
349
|
end
|
336
|
-
# rubocop:enable Metrics/MethodLength
|
337
350
|
|
338
351
|
def _destroy_chef_instance(chef, guid)
|
339
352
|
chef.destroy(
|
data/lib/formatron/aws.rb
CHANGED
@@ -9,31 +9,44 @@ class Formatron
|
|
9
9
|
|
10
10
|
REGIONS = {
|
11
11
|
'us-east-1' => {
|
12
|
-
|
13
|
-
|
14
|
-
'us-west-2' => {
|
15
|
-
ami: 'ami-8ee605bd'
|
12
|
+
'ubuntu' => 'ami-fce3c696',
|
13
|
+
'windows' => 'ami-3586ac5f'
|
16
14
|
},
|
17
15
|
'us-west-1' => {
|
18
|
-
|
16
|
+
'ubuntu' => 'ami-06116566',
|
17
|
+
'windows' => 'ami-95fd8bf5'
|
18
|
+
},
|
19
|
+
'us-west-2' => {
|
20
|
+
'ubuntu' => 'ami-9abea4fb',
|
21
|
+
'windows' => 'ami-df8767bf'
|
19
22
|
},
|
20
23
|
'eu-west-1' => {
|
21
|
-
|
24
|
+
'ubuntu' => 'ami-f95ef58a',
|
25
|
+
'windows' => 'ami-8519a9f6'
|
22
26
|
},
|
23
27
|
'eu-central-1' => {
|
24
|
-
|
28
|
+
'ubuntu' => 'ami-87564feb',
|
29
|
+
'windows' => 'ami-5dd2c931'
|
30
|
+
},
|
31
|
+
'ap-northeast-1' => {
|
32
|
+
'ubuntu' => 'ami-a21529cc',
|
33
|
+
'windows' => 'ami-14b8bc7a'
|
34
|
+
},
|
35
|
+
'ap-northeast-2' => {
|
36
|
+
'ubuntu' => 'ami-09dc1267',
|
37
|
+
'windows' => 'ami-d31dd3bd'
|
25
38
|
},
|
26
39
|
'ap-southeast-1' => {
|
27
|
-
|
40
|
+
'ubuntu' => 'ami-25c00c46',
|
41
|
+
'windows' => 'ami-9801cffb'
|
28
42
|
},
|
29
43
|
'ap-southeast-2' => {
|
30
|
-
|
31
|
-
|
32
|
-
'ap-northeast-1' => {
|
33
|
-
ami: 'ami-402e4c40'
|
44
|
+
'ubuntu' => 'ami-6c14310f',
|
45
|
+
'windows' => 'ami-db0a2db8'
|
34
46
|
},
|
35
47
|
'sa-east-1' => {
|
36
|
-
|
48
|
+
'ubuntu' => 'ami-0fb83963',
|
49
|
+
'windows' => 'ami-828e0dee'
|
37
50
|
}
|
38
51
|
}
|
39
52
|
|
data/lib/formatron/chef.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative 'chef/keys'
|
|
4
4
|
require_relative 'chef/berkshelf'
|
5
5
|
require_relative 'chef/knife'
|
6
6
|
require_relative 'chef/ssh'
|
7
|
+
require_relative 'chef/winrm'
|
7
8
|
|
8
9
|
class Formatron
|
9
10
|
# manage the instance provisioning with Chef
|
@@ -11,12 +12,16 @@ class Formatron
|
|
11
12
|
class Chef
|
12
13
|
# rubocop:disable Metrics/MethodLength
|
13
14
|
# rubocop:disable Metrics/ParameterLists
|
15
|
+
# rubocop:disable Metrics/AbcSize
|
14
16
|
def initialize(
|
17
|
+
directory:,
|
15
18
|
aws:,
|
16
19
|
bucket:,
|
17
20
|
name:,
|
18
21
|
target:,
|
19
22
|
ec2_key:,
|
23
|
+
administrator_name:,
|
24
|
+
administrator_password:,
|
20
25
|
username:,
|
21
26
|
organization:,
|
22
27
|
ssl_verify:,
|
@@ -28,6 +33,7 @@ class Formatron
|
|
28
33
|
configuration:,
|
29
34
|
databag_secret:
|
30
35
|
)
|
36
|
+
@working_directory = File.join directory, guid
|
31
37
|
@aws = aws
|
32
38
|
@name = name
|
33
39
|
@target = target
|
@@ -38,6 +44,7 @@ class Formatron
|
|
38
44
|
@bastions = bastions
|
39
45
|
chef_server_url = _chef_server_url
|
40
46
|
@keys = Keys.new(
|
47
|
+
directory: @working_directory,
|
41
48
|
aws: @aws,
|
42
49
|
bucket: bucket,
|
43
50
|
name: server_stack,
|
@@ -46,7 +53,10 @@ class Formatron
|
|
46
53
|
ec2_key: ec2_key
|
47
54
|
)
|
48
55
|
@knife = Knife.new(
|
56
|
+
directory: @working_directory,
|
49
57
|
keys: @keys,
|
58
|
+
administrator_name: administrator_name,
|
59
|
+
administrator_password: administrator_password,
|
50
60
|
chef_server_url: chef_server_url,
|
51
61
|
username: username,
|
52
62
|
organization: organization,
|
@@ -55,6 +65,7 @@ class Formatron
|
|
55
65
|
configuration: configuration
|
56
66
|
)
|
57
67
|
@berkshelf = Berkshelf.new(
|
68
|
+
directory: @working_directory,
|
58
69
|
keys: @keys,
|
59
70
|
chef_server_url: chef_server_url,
|
60
71
|
username: username,
|
@@ -63,7 +74,12 @@ class Formatron
|
|
63
74
|
@ssh = SSH.new(
|
64
75
|
keys: @keys
|
65
76
|
)
|
77
|
+
@winrm = WinRM.new(
|
78
|
+
administrator_name: administrator_name,
|
79
|
+
administrator_password: administrator_password
|
80
|
+
)
|
66
81
|
end
|
82
|
+
# rubocop:enable Metrics/AbcSize
|
67
83
|
# rubocop:enable Metrics/ParameterLists
|
68
84
|
# rubocop:enable Metrics/MethodLength
|
69
85
|
|
@@ -73,6 +89,7 @@ class Formatron
|
|
73
89
|
name: @server_stack,
|
74
90
|
target: @target
|
75
91
|
)
|
92
|
+
FileUtils.mkdir_p @working_directory
|
76
93
|
@keys.init
|
77
94
|
@knife.init
|
78
95
|
@berkshelf.init
|
@@ -81,6 +98,7 @@ class Formatron
|
|
81
98
|
# rubocop:disable Metrics/MethodLength
|
82
99
|
# rubocop:disable Metrics/AbcSize
|
83
100
|
def provision(
|
101
|
+
os:,
|
84
102
|
sub_domain:,
|
85
103
|
guid:,
|
86
104
|
cookbook:,
|
@@ -113,6 +131,7 @@ class Formatron
|
|
113
131
|
@berkshelf.upload environment: guid, cookbook: cookbook
|
114
132
|
if @knife.node_exists? guid: guid
|
115
133
|
_reprovision_node(
|
134
|
+
os: os,
|
116
135
|
bastion_hostname: bastion_hostname,
|
117
136
|
guid: guid,
|
118
137
|
cookbook_name: cookbook_name,
|
@@ -120,6 +139,7 @@ class Formatron
|
|
120
139
|
)
|
121
140
|
else
|
122
141
|
_bootstrap_node(
|
142
|
+
os: os,
|
123
143
|
bastion_hostname: bastion_hostname,
|
124
144
|
guid: guid,
|
125
145
|
cookbook_name: cookbook_name,
|
@@ -132,19 +152,22 @@ class Formatron
|
|
132
152
|
|
133
153
|
# rubocop:disable Metrics/MethodLength
|
134
154
|
def _reprovision_node(
|
155
|
+
os:,
|
135
156
|
bastion_hostname:,
|
136
157
|
guid:,
|
137
158
|
cookbook_name:,
|
138
159
|
hostname:
|
139
160
|
)
|
140
|
-
if
|
161
|
+
if _bootstrapped?(
|
162
|
+
os: os,
|
141
163
|
bastion_hostname: bastion_hostname,
|
142
164
|
hostname: hostname
|
143
165
|
)
|
144
166
|
Formatron::LOG.info do
|
145
167
|
"Run chef-client on existing node #{guid}"
|
146
168
|
end
|
147
|
-
|
169
|
+
_run_chef_client(
|
170
|
+
os: os,
|
148
171
|
bastion_hostname: bastion_hostname,
|
149
172
|
hostname: hostname
|
150
173
|
)
|
@@ -162,6 +185,7 @@ class Formatron
|
|
162
185
|
end
|
163
186
|
@knife.delete_client client: guid
|
164
187
|
_bootstrap_node(
|
188
|
+
os: os,
|
165
189
|
bastion_hostname: bastion_hostname,
|
166
190
|
guid: guid,
|
167
191
|
cookbook_name: cookbook_name,
|
@@ -171,8 +195,31 @@ class Formatron
|
|
171
195
|
end
|
172
196
|
# rubocop:enable Metrics/MethodLength
|
173
197
|
|
198
|
+
def _bootstrapped?(os:, bastion_hostname:, hostname:)
|
199
|
+
if os.eql? 'windows'
|
200
|
+
@winrm.bootstrapped? hostname: hostname
|
201
|
+
else
|
202
|
+
@ssh.bootstrapped?(
|
203
|
+
bastion_hostname: bastion_hostname,
|
204
|
+
hostname: hostname
|
205
|
+
)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def _run_chef_client(os:, bastion_hostname:, hostname:)
|
210
|
+
if os.eql? 'windows'
|
211
|
+
@winrm.run_chef_client hostname: hostname
|
212
|
+
else
|
213
|
+
@ssh.run_chef_client(
|
214
|
+
bastion_hostname: bastion_hostname,
|
215
|
+
hostname: hostname
|
216
|
+
)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
174
220
|
# rubocop:disable Metrics/MethodLength
|
175
221
|
def _bootstrap_node(
|
222
|
+
os:,
|
176
223
|
bastion_hostname:,
|
177
224
|
guid:,
|
178
225
|
cookbook_name:,
|
@@ -182,6 +229,7 @@ class Formatron
|
|
182
229
|
"Bootstrap node #{guid}"
|
183
230
|
end
|
184
231
|
@knife.bootstrap(
|
232
|
+
os: os,
|
185
233
|
bastion_hostname: bastion_hostname,
|
186
234
|
guid: guid,
|
187
235
|
cookbook: cookbook_name,
|
@@ -214,12 +262,6 @@ class Formatron
|
|
214
262
|
end
|
215
263
|
# rubocop:enable Metrics/MethodLength
|
216
264
|
|
217
|
-
def unlink
|
218
|
-
@keys.unlink
|
219
|
-
@knife.unlink
|
220
|
-
@berkshelf.unlink
|
221
|
-
end
|
222
|
-
|
223
265
|
def _chef_server_url
|
224
266
|
"https://#{@chef_sub_domain}.#{@hosted_zone_name}" \
|
225
267
|
"/organizations/#{@organization}"
|
@@ -233,7 +275,9 @@ class Formatron
|
|
233
275
|
:_chef_server_url,
|
234
276
|
:_hostname,
|
235
277
|
:_bootstrap_node,
|
236
|
-
:_reprovision_node
|
278
|
+
:_reprovision_node,
|
279
|
+
:_bootstrapped?,
|
280
|
+
:_run_chef_client
|
237
281
|
)
|
238
282
|
end
|
239
283
|
# rubocop:enable Metrics/ClassLength
|
@@ -17,39 +17,43 @@ class Formatron
|
|
17
17
|
}
|
18
18
|
}
|
19
19
|
EOH
|
20
|
+
CONFIG_FILE = 'berkshelf.json'
|
20
21
|
|
21
|
-
|
22
|
+
# rubocop:disable Metrics/MethodLength
|
23
|
+
def initialize(
|
24
|
+
directory:,
|
25
|
+
keys:,
|
26
|
+
chef_server_url:,
|
27
|
+
username:,
|
28
|
+
ssl_verify:
|
29
|
+
)
|
30
|
+
@config_file = File.join directory, CONFIG_FILE
|
22
31
|
@keys = keys
|
23
32
|
@chef_server_url = chef_server_url
|
24
33
|
@username = username
|
25
34
|
@ssl_verify = ssl_verify
|
26
35
|
end
|
36
|
+
# rubocop:enable Metrics/MethodLength
|
27
37
|
|
28
38
|
def init
|
29
|
-
@config_file
|
30
|
-
@config_file.write CONFIG_FILE_CONTENTS % {
|
39
|
+
File.write(@config_file, CONFIG_FILE_CONTENTS % {
|
31
40
|
server_url: @chef_server_url,
|
32
41
|
user: @username,
|
33
42
|
key_file: @keys.user_key,
|
34
43
|
ssl_verify: @ssl_verify
|
35
|
-
}
|
36
|
-
@config_file.close
|
44
|
+
})
|
37
45
|
end
|
38
46
|
|
39
47
|
def upload(cookbook:, environment:)
|
40
48
|
# rubocop:disable Metrics/LineLength
|
41
49
|
command = "berks install -b #{File.join(cookbook, 'Berksfile')}"
|
42
50
|
fail "failed to download cookbooks for opscode environment: #{environment}" unless Util::Shell.exec command
|
43
|
-
command = "berks upload -c #{@config_file
|
51
|
+
command = "berks upload -c #{@config_file} -b #{File.join(cookbook, 'Berksfile')}"
|
44
52
|
fail "failed to upload cookbooks for opscode environment: #{environment}" unless Util::Shell.exec command
|
45
|
-
command = "berks apply #{environment} -c #{@config_file
|
53
|
+
command = "berks apply #{environment} -c #{@config_file} -b #{File.join(cookbook, 'Berksfile.lock')}"
|
46
54
|
fail "failed to apply cookbooks to opscode environment: #{environment}" unless Util::Shell.exec command
|
47
55
|
# rubocop:enable Metrics/LineLength
|
48
56
|
end
|
49
|
-
|
50
|
-
def unlink
|
51
|
-
@config_file.unlink unless @config_file.nil?
|
52
|
-
end
|
53
57
|
end
|
54
58
|
end
|
55
59
|
end
|