11#!/opt/puppetlabs/puppet/bin/ruby 
22# frozen_string_literal: true 
33
4- # 
4+ require  'uri' 
5+ require  'net/https' 
56require  'json' 
67require  'open3' 
8+ require  'timeout' 
79
810def  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 
2632end 
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+ 
2880main 
0 commit comments