Skip to content

Commit a475b88

Browse files
authored
Merge pull request #122 from puppetlabs/infra-wait-until-connected
Wait until nodes connected before infra upgrade
2 parents d2332cc + ba94407 commit a475b88

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Documentation and README update
1212
### Bugfixes
1313

1414
- Fixed GH-118, wherein a compiler would unnecessarily send duplicate work to an extra configured PuppetDB endpoint.
15+
- Puppet infra upgrade operations now always wait until target nodes are connected before attempting an operation
1516

1617
### Improvements
1718

tasks/puppet_infra_upgrade.json

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
"token_file": {
1313
"type": "Optional[String]",
1414
"description": "The path to the token file to use"
15+
},
16+
"wait_until_connected_timeout": {
17+
"type": "Integer",
18+
"description": "How many seconds to wait for targets to be connected to the orchestrator",
19+
"default": 120
1520
}
1621
},
1722
"input_method": "stdin",

tasks/puppet_infra_upgrade.rb

+57-5
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
#!/opt/puppetlabs/puppet/bin/ruby
22
# frozen_string_literal: true
33

4-
#
4+
require 'uri'
5+
require 'net/https'
56
require 'json'
67
require 'open3'
8+
require 'timeout'
79

810
def main
9-
params = JSON.parse(STDIN.read)
10-
type = params['type']
11-
targets = params['targets']
11+
params = JSON.parse(STDIN.read)
12+
type = params['type']
13+
targets = params['targets']
14+
timeout = params['wait_until_connected_timeout']
15+
token_file = params['token_file'] || '/root/.puppetlabs/token'
1216

1317
exit 0 if targets.empty?
1418

1519
cmd = ['/opt/puppetlabs/bin/puppet-infrastructure', '--render-as', 'json', 'upgrade']
16-
cmd << '--token-file' << params['token_file'] unless params['token_file'].nil?
20+
cmd << '--token-file' << token_file unless params['token_file'].nil?
1721
cmd << type << targets.join(',')
1822

23+
wait_until_connected(nodes: targets, token_file: token_file, timeout: timeout)
24+
1925
stdouterr, status = Open3.capture2e(*cmd)
2026
puts stdouterr
2127
if status.success?
@@ -25,4 +31,50 @@ def main
2531
end
2632
end
2733

34+
def inventory_uri
35+
@inventory_uri ||= URI.parse('https://localhost:8143/orchestrator/v1/inventory')
36+
end
37+
38+
def request_object(nodes:, token_file:)
39+
token = File.read('/root/.puppetlabs/token')
40+
body = {
41+
'nodes' => nodes,
42+
}.to_json
43+
44+
request = Net::HTTP::Post.new(inventory_uri.request_uri)
45+
request['Content-Type'] = 'application/json'
46+
request['X-Authentication'] = token
47+
request.body = body
48+
49+
request
50+
end
51+
52+
def http_object
53+
http = Net::HTTP.new(inventory_uri.host, inventory_uri.port)
54+
http.use_ssl = true
55+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
56+
57+
http
58+
end
59+
60+
def wait_until_connected(nodes:, token_file:, timeout: 120)
61+
http = http_object
62+
request = request_object(nodes: nodes, token_file: token_file)
63+
inventory = {}
64+
Timeout::timeout(timeout) do
65+
loop do
66+
response = http.request(request)
67+
raise unless response.is_a? Net::HTTPSuccess
68+
inventory = JSON.parse(response.body)
69+
break if inventory['items'].all? { |item| item['connected'] }
70+
sleep(1)
71+
end
72+
end
73+
rescue Timeout::Error
74+
raise "Timed out waiting for nodes to be connected to orchestrator: " +
75+
inventory['items'].select { |item| !item['connected'] }
76+
.map { |item| item['name'] }
77+
.to_s
78+
end
79+
2880
main

0 commit comments

Comments
 (0)