formatron 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f65ce71a403a7fb9643dc55ded5f5db6e29ed56a
4
- data.tar.gz: 017ba0b1ecf0fb92becc855038b3bc1023bba5cc
3
+ metadata.gz: e2901f1a146d9b969d04f487d57f0ff26a85db1b
4
+ data.tar.gz: 154a154b9e9f920fcccb41add3563dddbb6f4b18
5
5
  SHA512:
6
- metadata.gz: 719acdc0c0e57bb503253f1a37c4b9543701a2112d9a069a4488ad50fc7b2a524d84d83b96771a3a683183652bfcb6d3c880f13385c0b0ea57616ef89b0de8d2
7
- data.tar.gz: e429955eade1cd8f89039e43991583f02b47d00152a7389e120f133aa360ab072d6ec9bc7eb7b57a1c9993af12be21b5466864c533747adf49e4b2f8fe2c7dfe
6
+ metadata.gz: 0a120f2f78037c737316853b5aedf94baed0d0e6dadc90ed55a636e3a165c94e6992f5b37fa68f12408d61f9fe7b69c23d6a0e295d924888a86a47deb47988d0
7
+ data.tar.gz: 8389d7122ed58e0ba66408c674da5e9a6123fbb1c255a78502ea2b706741039f99e9e491f687612e8a80620ba8203377daf78b15dda79411b33b04a0aa38119b
@@ -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
@@ -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
@@ -1,4 +1,4 @@
1
1
  # add version to class
2
2
  class Formatron
3
- VERSION = '0.1.10'
3
+ VERSION = '0.1.11'
4
4
  end
@@ -0,0 +1,12 @@
1
+ class Formatron
2
+ module Support
3
+ # Stub S3 get_object response class
4
+ class SSHData
5
+ attr_reader :read_long
6
+
7
+ def initialize(data)
8
+ @read_long = data
9
+ end
10
+ end
11
+ end
12
+ end
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.10
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: 2015-12-19 00:00:00.000000000 Z
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.4.5.1
419
+ rubygems_version: 2.2.2
417
420
  signing_key:
418
421
  specification_version: 4
419
422
  summary: AWS/Chef Deployment Tool