formatron 0.1.10 → 0.1.11
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/lib/formatron/chef/knife.rb +5 -0
- data/lib/formatron/chef/ssh.rb +37 -0
- data/lib/formatron/chef.rb +74 -2
- data/lib/formatron/util/ssh.rb +47 -0
- data/lib/formatron/version.rb +1 -1
- data/support/ssh_data.rb +12 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2901f1a146d9b969d04f487d57f0ff26a85db1b
|
4
|
+
data.tar.gz: 154a154b9e9f920fcccb41add3563dddbb6f4b18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a120f2f78037c737316853b5aedf94baed0d0e6dadc90ed55a636e3a165c94e6992f5b37fa68f12408d61f9fe7b69c23d6a0e295d924888a86a47deb47988d0
|
7
|
+
data.tar.gz: 8389d7122ed58e0ba66408c674da5e9a6123fbb1c255a78502ea2b706741039f99e9e491f687612e8a80620ba8203377daf78b15dda79411b33b04a0aa38119b
|
data/lib/formatron/chef/knife.rb
CHANGED
@@ -150,6 +150,11 @@ class Formatron
|
|
150
150
|
# rubocop:enable Metrics/LineLength
|
151
151
|
end
|
152
152
|
|
153
|
+
def node_exists?(guid:)
|
154
|
+
command = "knife node show #{guid} -c #{@knife_file.path}"
|
155
|
+
Util::Shell.exec command
|
156
|
+
end
|
157
|
+
|
153
158
|
def unlink
|
154
159
|
@knife_file.unlink unless @knife_file.nil?
|
155
160
|
@databag_secret_file.unlink unless @databag_secret_file.nil?
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'formatron/util/ssh'
|
2
|
+
|
3
|
+
class Formatron
|
4
|
+
class Chef
|
5
|
+
# Perform commands on chef nodes over SSH
|
6
|
+
class SSH
|
7
|
+
SSH_USER = 'ubuntu'
|
8
|
+
|
9
|
+
def initialize(keys:)
|
10
|
+
@keys = keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_chef_client(hostname:, bastion_hostname:)
|
14
|
+
Formatron::Util::SSH.exec(
|
15
|
+
hostname: hostname,
|
16
|
+
bastion_hostname: bastion_hostname,
|
17
|
+
user: SSH_USER,
|
18
|
+
key: @keys.ec2_key,
|
19
|
+
command: 'sudo chef-client'
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def bootstrapped?(hostname:, bastion_hostname:)
|
24
|
+
Formatron::Util::SSH.exec(
|
25
|
+
hostname: hostname,
|
26
|
+
bastion_hostname: bastion_hostname,
|
27
|
+
user: SSH_USER,
|
28
|
+
key: @keys.ec2_key,
|
29
|
+
command: '[ -f /etc/chef/client.pem ]'
|
30
|
+
)
|
31
|
+
true
|
32
|
+
rescue
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/formatron/chef.rb
CHANGED
@@ -3,6 +3,7 @@ require 'formatron/logger'
|
|
3
3
|
require_relative 'chef/keys'
|
4
4
|
require_relative 'chef/berkshelf'
|
5
5
|
require_relative 'chef/knife'
|
6
|
+
require_relative 'chef/ssh'
|
6
7
|
|
7
8
|
class Formatron
|
8
9
|
# manage the instance provisioning with Chef
|
@@ -59,6 +60,9 @@ class Formatron
|
|
59
60
|
username: username,
|
60
61
|
ssl_verify: ssl_verify
|
61
62
|
)
|
63
|
+
@ssh = SSH.new(
|
64
|
+
keys: @keys
|
65
|
+
)
|
62
66
|
end
|
63
67
|
# rubocop:enable Metrics/ParameterLists
|
64
68
|
# rubocop:enable Metrics/MethodLength
|
@@ -107,6 +111,73 @@ class Formatron
|
|
107
111
|
end
|
108
112
|
@knife.create_environment environment: guid
|
109
113
|
@berkshelf.upload environment: guid, cookbook: cookbook
|
114
|
+
if @knife.node_exists? guid: guid
|
115
|
+
_reprovision_node(
|
116
|
+
bastion_hostname: bastion_hostname,
|
117
|
+
guid: guid,
|
118
|
+
cookbook_name: cookbook_name,
|
119
|
+
hostname: hostname
|
120
|
+
)
|
121
|
+
else
|
122
|
+
_bootstrap_node(
|
123
|
+
bastion_hostname: bastion_hostname,
|
124
|
+
guid: guid,
|
125
|
+
cookbook_name: cookbook_name,
|
126
|
+
hostname: hostname
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
# rubocop:enable Metrics/AbcSize
|
131
|
+
# rubocop:enable Metrics/MethodLength
|
132
|
+
|
133
|
+
# rubocop:disable Metrics/MethodLength
|
134
|
+
def _reprovision_node(
|
135
|
+
bastion_hostname:,
|
136
|
+
guid:,
|
137
|
+
cookbook_name:,
|
138
|
+
hostname:
|
139
|
+
)
|
140
|
+
if @ssh.bootstrapped?(
|
141
|
+
bastion_hostname: bastion_hostname,
|
142
|
+
hostname: hostname
|
143
|
+
)
|
144
|
+
Formatron::LOG.info do
|
145
|
+
"Run chef-client on existing node #{guid}"
|
146
|
+
end
|
147
|
+
@ssh.run_chef_client(
|
148
|
+
bastion_hostname: bastion_hostname,
|
149
|
+
hostname: hostname
|
150
|
+
)
|
151
|
+
else
|
152
|
+
Formatron::LOG.info do
|
153
|
+
"node #{guid} exists but has not been bootstrapped, " \
|
154
|
+
'likely recreated so deleting node and bootstrapping again'
|
155
|
+
end
|
156
|
+
Formatron::LOG.info do
|
157
|
+
"Deleting node '#{guid}' from chef server: #{@chef_sub_domain}"
|
158
|
+
end
|
159
|
+
@knife.delete_node node: guid
|
160
|
+
Formatron::LOG.info do
|
161
|
+
"Deleting client '#{guid}' from chef server: #{@chef_sub_domain}"
|
162
|
+
end
|
163
|
+
@knife.delete_client client: guid
|
164
|
+
_bootstrap_node(
|
165
|
+
bastion_hostname: bastion_hostname,
|
166
|
+
guid: guid,
|
167
|
+
cookbook_name: cookbook_name,
|
168
|
+
hostname: hostname
|
169
|
+
)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
# rubocop:enable Metrics/MethodLength
|
173
|
+
|
174
|
+
# rubocop:disable Metrics/MethodLength
|
175
|
+
def _bootstrap_node(
|
176
|
+
bastion_hostname:,
|
177
|
+
guid:,
|
178
|
+
cookbook_name:,
|
179
|
+
hostname:
|
180
|
+
)
|
110
181
|
Formatron::LOG.info do
|
111
182
|
"Bootstrap node #{guid}"
|
112
183
|
end
|
@@ -117,7 +188,6 @@ class Formatron
|
|
117
188
|
hostname: hostname
|
118
189
|
)
|
119
190
|
end
|
120
|
-
# rubocop:enable Metrics/AbcSize
|
121
191
|
# rubocop:enable Metrics/MethodLength
|
122
192
|
|
123
193
|
# rubocop:disable Metrics/MethodLength
|
@@ -161,7 +231,9 @@ class Formatron
|
|
161
231
|
|
162
232
|
private(
|
163
233
|
:_chef_server_url,
|
164
|
-
:_hostname
|
234
|
+
:_hostname,
|
235
|
+
:_bootstrap_node,
|
236
|
+
:_reprovision_node
|
165
237
|
)
|
166
238
|
end
|
167
239
|
# rubocop:enable Metrics/ClassLength
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
require 'net/ssh/proxy/command'
|
3
|
+
require 'formatron/logger'
|
4
|
+
|
5
|
+
class Formatron
|
6
|
+
module Util
|
7
|
+
# Perform commands on chef nodes over SSH
|
8
|
+
class SSH
|
9
|
+
# rubocop:disable Metrics/MethodLength
|
10
|
+
# rubocop:disable Metrics/AbcSize
|
11
|
+
def self.exec(hostname:, bastion_hostname:, user:, key:, command:)
|
12
|
+
proxy_command = Net::SSH::Proxy::Command.new(
|
13
|
+
"ssh #{user}@#{bastion_hostname} -W %h:%p"
|
14
|
+
) unless hostname.eql? bastion_hostname
|
15
|
+
Net::SSH.start(
|
16
|
+
hostname,
|
17
|
+
user,
|
18
|
+
keys: [key],
|
19
|
+
proxy: proxy_command
|
20
|
+
) do |ssh|
|
21
|
+
ssh.open_channel do |channel|
|
22
|
+
channel.exec(command) do |_ch, success|
|
23
|
+
fail "failed to start command: #{command}" unless success
|
24
|
+
channel.on_request('exit-status') do |_ch, data|
|
25
|
+
status = data.read_long
|
26
|
+
fail "`#{command}` exited with code #{status}" if status != 0
|
27
|
+
end
|
28
|
+
channel.on_data do |_ch, data|
|
29
|
+
data.each_line do |line|
|
30
|
+
Formatron::LOG.info { line.chomp }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
channel.on_extended_data do |_ch, _type, data|
|
34
|
+
data.each_line do |line|
|
35
|
+
Formatron::LOG.info { line.chomp }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
ssh.loop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# rubocop:enable Metrics/AbcSize
|
44
|
+
# rubocop:enable Metrics/MethodLength
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/formatron/version.rb
CHANGED
data/support/ssh_data.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formatron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Halliday
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -307,6 +307,7 @@ files:
|
|
307
307
|
- lib/formatron/chef/berkshelf.rb
|
308
308
|
- lib/formatron/chef/keys.rb
|
309
309
|
- lib/formatron/chef/knife.rb
|
310
|
+
- lib/formatron/chef/ssh.rb
|
310
311
|
- lib/formatron/chef_clients.rb
|
311
312
|
- lib/formatron/cli.rb
|
312
313
|
- lib/formatron/cli/completion.rb
|
@@ -385,6 +386,7 @@ files:
|
|
385
386
|
- lib/formatron/s3/path.rb
|
386
387
|
- lib/formatron/util/dsl.rb
|
387
388
|
- lib/formatron/util/shell.rb
|
389
|
+
- lib/formatron/util/ssh.rb
|
388
390
|
- lib/formatron/util/vpc.rb
|
389
391
|
- lib/formatron/version.rb
|
390
392
|
- support/cloudformation_describe_stacks_response.rb
|
@@ -392,6 +394,7 @@ files:
|
|
392
394
|
- support/route53_get_hosted_zone_response.rb
|
393
395
|
- support/s3_get_object_response.rb
|
394
396
|
- support/s3_list_objects_response.rb
|
397
|
+
- support/ssh_data.rb
|
395
398
|
- support/template_test.rb
|
396
399
|
homepage: https://github.com/pghalliday/formatron
|
397
400
|
licenses:
|
@@ -413,7 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
416
|
version: '0'
|
414
417
|
requirements: []
|
415
418
|
rubyforge_project:
|
416
|
-
rubygems_version: 2.
|
419
|
+
rubygems_version: 2.2.2
|
417
420
|
signing_key:
|
418
421
|
specification_version: 4
|
419
422
|
summary: AWS/Chef Deployment Tool
|