bolt 0.17.1 → 0.17.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +25 -13
  3. data/lib/bolt/cli.rb +45 -15
  4. data/lib/bolt/config.rb +48 -132
  5. data/lib/bolt/executor.rb +3 -10
  6. data/lib/bolt/inventory.rb +15 -1
  7. data/lib/bolt/puppetdb.rb +11 -0
  8. data/lib/bolt/puppetdb/client.rb +68 -0
  9. data/lib/bolt/puppetdb/config.rb +76 -0
  10. data/lib/bolt/target.rb +5 -4
  11. data/lib/bolt/transport/base.rb +11 -2
  12. data/lib/bolt/transport/local.rb +11 -5
  13. data/lib/bolt/transport/orch.rb +16 -5
  14. data/lib/bolt/transport/ssh.rb +32 -1
  15. data/lib/bolt/transport/ssh/connection.rb +17 -10
  16. data/lib/bolt/transport/winrm.rb +18 -1
  17. data/lib/bolt/transport/winrm/connection.rb +15 -16
  18. data/lib/bolt/util.rb +15 -0
  19. data/lib/bolt/version.rb +1 -1
  20. data/lib/bolt_ext/puppetdb_inventory.rb +5 -135
  21. data/vendored/facter/lib/facter/ec2/rest.rb +1 -1
  22. data/vendored/hiera/lib/hiera/version.rb +1 -1
  23. data/vendored/puppet/lib/puppet/application/agent.rb +1 -3
  24. data/vendored/puppet/lib/puppet/application/apply.rb +2 -4
  25. data/vendored/puppet/lib/puppet/application/cert.rb +6 -1
  26. data/vendored/puppet/lib/puppet/application/device.rb +100 -13
  27. data/vendored/puppet/lib/puppet/application/facts.rb +5 -0
  28. data/vendored/puppet/lib/puppet/application/lookup.rb +11 -1
  29. data/vendored/puppet/lib/puppet/configurer.rb +17 -4
  30. data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +1 -1
  31. data/vendored/puppet/lib/puppet/datatypes.rb +1 -1
  32. data/vendored/puppet/lib/puppet/defaults.rb +1 -1
  33. data/vendored/puppet/lib/puppet/environments.rb +2 -2
  34. data/vendored/puppet/lib/puppet/error.rb +6 -3
  35. data/vendored/puppet/lib/puppet/external/dot.rb +0 -7
  36. data/vendored/puppet/lib/puppet/external/nagios/parser.rb +1 -1
  37. data/vendored/puppet/lib/puppet/face/config.rb +41 -8
  38. data/vendored/puppet/lib/puppet/face/epp.rb +30 -5
  39. data/vendored/puppet/lib/puppet/face/facts.rb +49 -0
  40. data/vendored/puppet/lib/puppet/face/help.rb +33 -35
  41. data/vendored/puppet/lib/puppet/face/man.rb +55 -12
  42. data/vendored/puppet/lib/puppet/face/parser.rb +30 -3
  43. data/vendored/puppet/lib/puppet/file_bucket/file.rb +0 -2
  44. data/vendored/puppet/lib/puppet/file_serving/base.rb +10 -10
  45. data/vendored/puppet/lib/puppet/functions.rb +1 -3
  46. data/vendored/puppet/lib/puppet/functions/alert.rb +1 -1
  47. data/vendored/puppet/lib/puppet/functions/all.rb +6 -6
  48. data/vendored/puppet/lib/puppet/functions/annotate.rb +10 -10
  49. data/vendored/puppet/lib/puppet/functions/any.rb +6 -6
  50. data/vendored/puppet/lib/puppet/functions/assert_type.rb +4 -4
  51. data/vendored/puppet/lib/puppet/functions/binary_file.rb +14 -2
  52. data/vendored/puppet/lib/puppet/functions/break.rb +31 -2
  53. data/vendored/puppet/lib/puppet/functions/call.rb +4 -4
  54. data/vendored/puppet/lib/puppet/functions/contain.rb +19 -3
  55. data/vendored/puppet/lib/puppet/functions/convert_to.rb +6 -5
  56. data/vendored/puppet/lib/puppet/functions/crit.rb +1 -1
  57. data/vendored/puppet/lib/puppet/functions/debug.rb +1 -1
  58. data/vendored/puppet/lib/puppet/functions/defined.rb +11 -9
  59. data/vendored/puppet/lib/puppet/functions/dig.rb +26 -2
  60. data/vendored/puppet/lib/puppet/functions/each.rb +8 -8
  61. data/vendored/puppet/lib/puppet/functions/emerg.rb +1 -1
  62. data/vendored/puppet/lib/puppet/functions/empty.rb +79 -0
  63. data/vendored/puppet/lib/puppet/functions/err.rb +1 -1
  64. data/vendored/puppet/lib/puppet/functions/filter.rb +7 -7
  65. data/vendored/puppet/lib/puppet/functions/find_file.rb +15 -1
  66. data/vendored/puppet/lib/puppet/functions/flatten.rb +64 -0
  67. data/vendored/puppet/lib/puppet/functions/hiera.rb +6 -6
  68. data/vendored/puppet/lib/puppet/functions/hiera_array.rb +6 -6
  69. data/vendored/puppet/lib/puppet/functions/hiera_hash.rb +6 -6
  70. data/vendored/puppet/lib/puppet/functions/hiera_include.rb +8 -8
  71. data/vendored/puppet/lib/puppet/functions/include.rb +28 -2
  72. data/vendored/puppet/lib/puppet/functions/info.rb +1 -1
  73. data/vendored/puppet/lib/puppet/functions/inline_epp.rb +2 -2
  74. data/vendored/puppet/lib/puppet/functions/join.rb +56 -0
  75. data/vendored/puppet/lib/puppet/functions/keys.rb +25 -0
  76. data/vendored/puppet/lib/puppet/functions/length.rb +44 -0
  77. data/vendored/puppet/lib/puppet/functions/lest.rb +39 -1
  78. data/vendored/puppet/lib/puppet/functions/map.rb +10 -9
  79. data/vendored/puppet/lib/puppet/functions/match.rb +6 -6
  80. data/vendored/puppet/lib/puppet/functions/new.rb +995 -2
  81. data/vendored/puppet/lib/puppet/functions/next.rb +1 -1
  82. data/vendored/puppet/lib/puppet/functions/notice.rb +1 -1
  83. data/vendored/puppet/lib/puppet/functions/reduce.rb +6 -6
  84. data/vendored/puppet/lib/puppet/functions/regsubst.rb +9 -3
  85. data/vendored/puppet/lib/puppet/functions/require.rb +36 -2
  86. data/vendored/puppet/lib/puppet/functions/return.rb +1 -1
  87. data/vendored/puppet/lib/puppet/functions/reverse_each.rb +71 -2
  88. data/vendored/puppet/lib/puppet/functions/slice.rb +23 -9
  89. data/vendored/puppet/lib/puppet/functions/split.rb +12 -10
  90. data/vendored/puppet/lib/puppet/functions/step.rb +73 -1
  91. data/vendored/puppet/lib/puppet/functions/strftime.rb +176 -2
  92. data/vendored/puppet/lib/puppet/functions/then.rb +65 -2
  93. data/vendored/puppet/lib/puppet/functions/tree_each.rb +19 -19
  94. data/vendored/puppet/lib/puppet/functions/type.rb +42 -1
  95. data/vendored/puppet/lib/puppet/functions/unique.rb +13 -13
  96. data/vendored/puppet/lib/puppet/functions/unwrap.rb +8 -4
  97. data/vendored/puppet/lib/puppet/functions/values.rb +25 -0
  98. data/vendored/puppet/lib/puppet/functions/versioncmp.rb +1 -1
  99. data/vendored/puppet/lib/puppet/functions/warning.rb +1 -1
  100. data/vendored/puppet/lib/puppet/functions/with.rb +6 -4
  101. data/vendored/puppet/lib/puppet/indirector/certificate_status/file.rb +1 -1
  102. data/vendored/puppet/lib/puppet/indirector/facts/facter.rb +1 -3
  103. data/vendored/puppet/lib/puppet/indirector/facts/rest.rb +21 -0
  104. data/vendored/puppet/lib/puppet/indirector/facts/yaml.rb +0 -4
  105. data/vendored/puppet/lib/puppet/indirector/file_content/http.rb +3 -1
  106. data/vendored/puppet/lib/puppet/indirector/indirection.rb +5 -3
  107. data/vendored/puppet/lib/puppet/indirector/request.rb +6 -2
  108. data/vendored/puppet/lib/puppet/module/task.rb +2 -2
  109. data/vendored/puppet/lib/puppet/module_tool/tar/mini.rb +57 -4
  110. data/vendored/puppet/lib/puppet/network/authconfig.rb +1 -1
  111. data/vendored/puppet/lib/puppet/network/http/api/indirected_routes.rb +1 -0
  112. data/vendored/puppet/lib/puppet/network/resolver.rb +1 -2
  113. data/vendored/puppet/lib/puppet/node.rb +4 -3
  114. data/vendored/puppet/lib/puppet/parser/compiler.rb +12 -5
  115. data/vendored/puppet/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +1 -1
  116. data/vendored/puppet/lib/puppet/parser/functions/fqdn_rand.rb +15 -4
  117. data/vendored/puppet/lib/puppet/parser/functions/new.rb +31 -46
  118. data/vendored/puppet/lib/puppet/parser/parser_factory.rb +1 -1
  119. data/vendored/puppet/lib/puppet/parser/resource.rb +1 -1
  120. data/vendored/puppet/lib/puppet/parser/type_loader.rb +11 -11
  121. data/vendored/puppet/lib/puppet/pops/evaluator/closure.rb +1 -1
  122. data/vendored/puppet/lib/puppet/pops/evaluator/collector_transformer.rb +1 -1
  123. data/vendored/puppet/lib/puppet/pops/evaluator/epp_evaluator.rb +2 -2
  124. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_resource_support.rb +2 -2
  125. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +5 -2
  126. data/vendored/puppet/lib/puppet/pops/functions/dispatch.rb +1 -1
  127. data/vendored/puppet/lib/puppet/pops/issue_reporter.rb +18 -1
  128. data/vendored/puppet/lib/puppet/pops/issues.rb +6 -3
  129. data/vendored/puppet/lib/puppet/pops/loader/ruby_data_type_instantiator.rb +1 -2
  130. data/vendored/puppet/lib/puppet/pops/loader/ruby_function_instantiator.rb +1 -2
  131. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +4 -4
  132. data/vendored/puppet/lib/puppet/pops/loader/type_definition_instantiator.rb +4 -1
  133. data/vendored/puppet/lib/puppet/pops/loaders.rb +18 -7
  134. data/vendored/puppet/lib/puppet/pops/lookup/global_data_provider.rb +1 -1
  135. data/vendored/puppet/lib/puppet/pops/model/factory.rb +6 -3
  136. data/vendored/puppet/lib/puppet/pops/model/model_tree_dumper.rb +4 -0
  137. data/vendored/puppet/lib/puppet/pops/model/pn_transformer.rb +400 -0
  138. data/vendored/puppet/lib/puppet/pops/parser/eparser.rb +1 -1
  139. data/vendored/puppet/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  140. data/vendored/puppet/lib/puppet/pops/parser/lexer_support.rb +3 -2
  141. data/vendored/puppet/lib/puppet/pops/parser/locator.rb +0 -2
  142. data/vendored/puppet/lib/puppet/pops/parser/pn_parser.rb +316 -0
  143. data/vendored/puppet/lib/puppet/pops/pcore.rb +17 -17
  144. data/vendored/puppet/lib/puppet/pops/pn.rb +236 -0
  145. data/vendored/puppet/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
  146. data/vendored/puppet/lib/puppet/pops/types/class_loader.rb +6 -3
  147. data/vendored/puppet/lib/puppet/pops/types/implementation_registry.rb +28 -35
  148. data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +3 -3
  149. data/vendored/puppet/lib/puppet/pops/types/p_timespan_type.rb +2 -2
  150. data/vendored/puppet/lib/puppet/pops/types/p_type_set_type.rb +24 -1
  151. data/vendored/puppet/lib/puppet/pops/types/ruby_generator.rb +3 -4
  152. data/vendored/puppet/lib/puppet/pops/types/type_calculator.rb +1 -1
  153. data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +0 -4
  154. data/vendored/puppet/lib/puppet/pops/types/type_mismatch_describer.rb +1 -1
  155. data/vendored/puppet/lib/puppet/pops/types/type_parser.rb +14 -7
  156. data/vendored/puppet/lib/puppet/pops/types/types.rb +1 -1
  157. data/vendored/puppet/lib/puppet/pops/utils.rb +2 -2
  158. data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +6 -2
  159. data/vendored/puppet/lib/puppet/provider/group/groupadd.rb +3 -1
  160. data/vendored/puppet/lib/puppet/provider/group/windows_adsi.rb +4 -7
  161. data/vendored/puppet/lib/puppet/provider/nameservice.rb +3 -3
  162. data/vendored/puppet/lib/puppet/provider/package/dnf.rb +1 -1
  163. data/vendored/puppet/lib/puppet/provider/package/gem.rb +1 -1
  164. data/vendored/puppet/lib/puppet/provider/package/pacman.rb +4 -4
  165. data/vendored/puppet/lib/puppet/provider/package/pip.rb +3 -3
  166. data/vendored/puppet/lib/puppet/provider/package/pkgdmg.rb +3 -3
  167. data/vendored/puppet/lib/puppet/provider/package/pkgutil.rb +2 -2
  168. data/vendored/puppet/lib/puppet/provider/package/portage.rb +9 -9
  169. data/vendored/puppet/lib/puppet/provider/package/zypper.rb +2 -2
  170. data/vendored/puppet/lib/puppet/provider/service/base.rb +1 -1
  171. data/vendored/puppet/lib/puppet/provider/service/smf.rb +3 -2
  172. data/vendored/puppet/lib/puppet/provider/user/useradd.rb +6 -2
  173. data/vendored/puppet/lib/puppet/provider/user/windows_adsi.rb +1 -1
  174. data/vendored/puppet/lib/puppet/provider/zfs/zfs.rb +3 -2
  175. data/vendored/puppet/lib/puppet/reference/configuration.rb +2 -0
  176. data/vendored/puppet/lib/puppet/reference/type.rb +11 -11
  177. data/vendored/puppet/lib/puppet/resource.rb +1 -1
  178. data/vendored/puppet/lib/puppet/resource/capability_finder.rb +2 -2
  179. data/vendored/puppet/lib/puppet/resource/catalog.rb +2 -2
  180. data/vendored/puppet/lib/puppet/resource/status.rb +9 -2
  181. data/vendored/puppet/lib/puppet/resource/type.rb +1 -1
  182. data/vendored/puppet/lib/puppet/settings.rb +31 -19
  183. data/vendored/puppet/lib/puppet/settings/base_setting.rb +5 -0
  184. data/vendored/puppet/lib/puppet/settings/config_file.rb +1 -1
  185. data/vendored/puppet/lib/puppet/settings/ttl_setting.rb +5 -0
  186. data/vendored/puppet/lib/puppet/ssl/certificate_factory.rb +2 -2
  187. data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +0 -2
  188. data/vendored/puppet/lib/puppet/transaction/additional_resource_generator.rb +2 -2
  189. data/vendored/puppet/lib/puppet/transaction/event.rb +1 -1
  190. data/vendored/puppet/lib/puppet/transaction/report.rb +1 -1
  191. data/vendored/puppet/lib/puppet/type.rb +9 -13
  192. data/vendored/puppet/lib/puppet/type/augeas.rb +2 -2
  193. data/vendored/puppet/lib/puppet/type/cron.rb +11 -6
  194. data/vendored/puppet/lib/puppet/type/exec.rb +1 -1
  195. data/vendored/puppet/lib/puppet/type/file.rb +4 -5
  196. data/vendored/puppet/lib/puppet/type/host.rb +1 -1
  197. data/vendored/puppet/lib/puppet/type/k5login.rb +30 -54
  198. data/vendored/puppet/lib/puppet/type/package.rb +3 -3
  199. data/vendored/puppet/lib/puppet/type/schedule.rb +12 -12
  200. data/vendored/puppet/lib/puppet/type/scheduled_task.rb +2 -2
  201. data/vendored/puppet/lib/puppet/type/ssh_authorized_key.rb +5 -5
  202. data/vendored/puppet/lib/puppet/type/sshkey.rb +2 -2
  203. data/vendored/puppet/lib/puppet/type/tidy.rb +9 -2
  204. data/vendored/puppet/lib/puppet/type/user.rb +1 -1
  205. data/vendored/puppet/lib/puppet/type/yumrepo.rb +25 -4
  206. data/vendored/puppet/lib/puppet/type/zfs.rb +4 -0
  207. data/vendored/puppet/lib/puppet/util.rb +0 -4
  208. data/vendored/puppet/lib/puppet/util/backups.rb +1 -1
  209. data/vendored/puppet/lib/puppet/util/http_proxy.rb +4 -2
  210. data/vendored/puppet/lib/puppet/util/inifile.rb +3 -4
  211. data/vendored/puppet/lib/puppet/util/log.rb +2 -5
  212. data/vendored/puppet/lib/puppet/util/network_device/cisco/facts.rb +1 -1
  213. data/vendored/puppet/lib/puppet/util/reference.rb +1 -8
  214. data/vendored/puppet/lib/puppet/util/tagging.rb +1 -1
  215. data/vendored/puppet/lib/puppet/util/warnings.rb +0 -2
  216. data/vendored/puppet/lib/puppet/util/windows/adsi.rb +15 -18
  217. data/vendored/puppet/lib/puppet/util/windows/com.rb +2 -1
  218. data/vendored/puppet/lib/puppet/util/windows/file.rb +2 -2
  219. data/vendored/puppet/lib/puppet/util/windows/principal.rb +7 -6
  220. data/vendored/puppet/lib/puppet/util/windows/sid.rb +60 -7
  221. data/vendored/puppet/lib/puppet/util/windows/taskscheduler.rb +0 -9
  222. data/vendored/puppet/lib/puppet/version.rb +1 -1
  223. data/vendored/puppet/lib/puppet_pal.rb +53 -48
  224. metadata +15 -2
@@ -7,10 +7,6 @@ require 'bolt/result'
7
7
  require 'bolt/config'
8
8
  require 'bolt/notifier'
9
9
  require 'bolt/result_set'
10
- require 'bolt/transport/ssh'
11
- require 'bolt/transport/winrm'
12
- require 'bolt/transport/orch'
13
- require 'bolt/transport/local'
14
10
 
15
11
  module Bolt
16
12
  class Executor
@@ -21,12 +17,9 @@ module Bolt
21
17
  @config = config
22
18
  @logger = Logging.logger[self]
23
19
 
24
- @transports = {
25
- 'ssh' => Concurrent::Delay.new { Bolt::Transport::SSH.new(config[:transports][:ssh] || {}) },
26
- 'winrm' => Concurrent::Delay.new { Bolt::Transport::WinRM.new(config[:transports][:winrm] || {}) },
27
- 'pcp' => Concurrent::Delay.new { Bolt::Transport::Orch.new(config[:transports][:pcp] || {}) },
28
- 'local' => Concurrent::Delay.new { Bolt::Transport::Local.new(config[:transports][:local] || {}) }
29
- }
20
+ @transports = Bolt::TRANSPORTS.each_with_object({}) do |(key, val), coll|
21
+ coll[key.to_s] = Concurrent::Delay.new { val.new }
22
+ end
30
23
 
31
24
  # If a specific elevated log level has been requested, honor that.
32
25
  # Otherwise, escalate the log level to "info" if running in plan mode, so
@@ -5,6 +5,8 @@ require 'bolt/inventory/group'
5
5
 
6
6
  module Bolt
7
7
  class Inventory
8
+ ENVIRONMENT_VAR = 'BOLT_INVENTORY'.freeze
9
+
8
10
  class ValidationError < Bolt::Error
9
11
  attr_accessor :path
10
12
  def initialize(message, offending_group)
@@ -37,7 +39,19 @@ module Bolt
37
39
  end
38
40
 
39
41
  def self.from_config(config)
40
- data = Bolt::Util.read_config_file(config[:inventoryfile], default_paths, 'inventory')
42
+ if ENV.include?(ENVIRONMENT_VAR)
43
+ begin
44
+ # rubocop:disable YAMLLoad
45
+ data = YAML.load(ENV[ENVIRONMENT_VAR])
46
+ # In older releases of psych SyntaxError is not a subclass of Exception
47
+ rescue Psych::SyntaxError
48
+ raise Bolt::CLIError, "Could not parse inventory from $#{ENVIRONMENT_VAR}"
49
+ rescue Psych::Exception
50
+ raise Bolt::CLIError, "Could not parse inventory from $#{ENVIRONMENT_VAR}"
51
+ end
52
+ else
53
+ data = Bolt::Util.read_config_file(config[:inventoryfile], default_paths, 'inventory')
54
+ end
41
55
 
42
56
  inventory = new(data, config)
43
57
  inventory.validate
@@ -0,0 +1,11 @@
1
+ require 'bolt/error'
2
+ require 'bolt/puppetdb/client'
3
+ require 'bolt/puppetdb/config'
4
+
5
+ module Bolt
6
+ class PuppetDBError < Bolt::Error
7
+ def initialize(msg)
8
+ super(msg, "bolt/puppetdb-error")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ require 'json'
2
+ require 'uri'
3
+ require 'httpclient'
4
+
5
+ module Bolt
6
+ module PuppetDB
7
+ class Client
8
+ def self.from_config(config)
9
+ uri = if config['server_urls'].is_a? String
10
+ config['server_urls']
11
+ else
12
+ config['server_urls'].first
13
+ end
14
+ uri = URI.parse(uri)
15
+ uri.port ||= 8081
16
+
17
+ cacert = File.expand_path(config['cacert'])
18
+ token = config.token
19
+
20
+ cert = config['cert']
21
+ key = config['key']
22
+
23
+ new(uri, cacert, token: token, cert: cert, key: key)
24
+ end
25
+
26
+ def initialize(uri, cacert, token: nil, cert: nil, key: nil)
27
+ @uri = uri
28
+ @cacert = cacert
29
+ @token = token
30
+ @cert = cert
31
+ @key = key
32
+ end
33
+
34
+ def query_certnames(query)
35
+ return [] unless query
36
+
37
+ body = JSON.generate(query: query)
38
+
39
+ response = http_client.post("#{@uri}/pdb/query/v4", body: body, header: headers)
40
+ if response.code != 200
41
+ raise Bolt::PuppetDBError, "Failed to query PuppetDB: #{response.body}"
42
+ else
43
+ results = JSON.parse(response.body)
44
+ if results.first && !results.first.key?('certname')
45
+ fields = results.first.keys
46
+ raise Bolt::PuppetDBError, "Query results did not contain a 'certname' field: got #{fields.join(', ')}"
47
+ end
48
+ results.map { |result| result['certname'] }.uniq
49
+ end
50
+ end
51
+
52
+ def http_client
53
+ return @http if @http
54
+ @http = HTTPClient.new
55
+ @http.ssl_config.set_client_cert_file(@cert, @key)
56
+ @http.ssl_config.add_trust_ca(@cacert)
57
+
58
+ @http
59
+ end
60
+
61
+ def headers
62
+ headers = { 'Content-Type' => 'application/json' }
63
+ headers['X-Authentication'] = @token if @token
64
+ headers
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,76 @@
1
+ require 'json'
2
+
3
+ module Bolt
4
+ module PuppetDB
5
+ class Config
6
+ DEFAULT_TOKEN = File.expand_path('~/.puppetlabs/token')
7
+ DEFAULT_CONFIG = File.expand_path('~/.puppetlabs/client-tools/puppetdb.conf')
8
+
9
+ def initialize(config_file, options)
10
+ @settings = load_config(config_file)
11
+ @settings.merge!(options)
12
+
13
+ expand_paths
14
+ validate
15
+ end
16
+
17
+ def load_config(filename)
18
+ if filename
19
+ if File.exist?(filename)
20
+ config = JSON.parse(File.read(filename))
21
+ else
22
+ raise Bolt::PuppetDBError, "config file #{filename} does not exist"
23
+ end
24
+ elsif File.exist?(DEFAULT_CONFIG)
25
+ config = JSON.parse(File.read(DEFAULT_CONFIG))
26
+ else
27
+ config = {}
28
+ end
29
+ config.fetch('puppetdb', {})
30
+ end
31
+
32
+ def token
33
+ return @token if @token
34
+ if @settings['token']
35
+ File.read(@settings['token'])
36
+ elsif File.exist?(DEFAULT_TOKEN)
37
+ File.read(DEFAULT_TOKEN)
38
+ end
39
+ end
40
+
41
+ def [](key)
42
+ @settings[key]
43
+ end
44
+
45
+ def expand_paths
46
+ %w[cacert cert key token].each do |file|
47
+ @settings[file] = File.expand_path(@settings[file]) if @settings[file]
48
+ end
49
+ end
50
+
51
+ def validate_file_exists(file)
52
+ if @settings[file] && !File.exist?(@settings[file])
53
+ raise Bolt::PuppetDBError, "#{file} file #{@settings[file]} does not exist"
54
+ end
55
+ end
56
+
57
+ def validate
58
+ unless @settings['server_urls']
59
+ raise Bolt::PuppetDBError, "server_urls must be specified"
60
+ end
61
+ unless @settings['cacert']
62
+ raise Bolt::PuppetDBError, "cacert must be specified"
63
+ end
64
+
65
+ if (@settings['cert'] && !@settings['key']) ||
66
+ (!@settings['cert'] && @settings['key'])
67
+ raise Bolt::PuppetDBError, "cert and key must be specified together"
68
+ end
69
+
70
+ validate_file_exists('cacert')
71
+ validate_file_exists('cert')
72
+ validate_file_exists('key')
73
+ end
74
+ end
75
+ end
76
+ end
@@ -14,6 +14,7 @@ module Bolt
14
14
  @uri = uri
15
15
  @uri_obj = parse(uri)
16
16
  @options = options || {}
17
+ @options.freeze
17
18
  end
18
19
 
19
20
  def update_conf(conf)
@@ -21,11 +22,11 @@ module Bolt
21
22
 
22
23
  t_conf = conf[:transports][protocol.to_sym]
23
24
  # Override url methods
24
- url_keys = %i[user password port]
25
- @user = t_conf[:user]
26
- @password = t_conf[:password]
27
- @port = t_conf[:port]
25
+ @user = t_conf['user']
26
+ @password = t_conf['password']
27
+ @port = t_conf['port']
28
28
 
29
+ url_keys = %w[user password port]
29
30
  @options = t_conf.reject { |k, _| url_keys.include?(k) }.merge(@options)
30
31
 
31
32
  self
@@ -39,7 +39,16 @@ module Bolt
39
39
 
40
40
  attr_reader :logger
41
41
 
42
- def initialize(_config)
42
+ # Returns options this transport supports
43
+ def self.options
44
+ raise NotImplementedError, "self.options() must be implemented by the transport class"
45
+ end
46
+
47
+ def self.validate(_options)
48
+ raise NotImplementedError, "self.validate() must be implemented by the transport class"
49
+ end
50
+
51
+ def initialize
43
52
  @logger = Logging.logger[self]
44
53
  end
45
54
 
@@ -57,7 +66,7 @@ module Bolt
57
66
  end
58
67
 
59
68
  def filter_options(target, options)
60
- if target.options[:run_as]
69
+ if target.options['run-as']
61
70
  options.reject { |k, _v| k == '_run_as' }
62
71
  else
63
72
  options
@@ -7,8 +7,14 @@ require 'bolt/result'
7
7
  module Bolt
8
8
  module Transport
9
9
  class Local < Base
10
- def initialize(config = nil)
11
- super(config)
10
+ def self.options
11
+ %w[tmpdir]
12
+ end
13
+
14
+ def self.validate(_options); end
15
+
16
+ def initialize
17
+ super
12
18
 
13
19
  if Gem.win_platform?
14
20
  raise NotImplementedError, "The local transport is not yet implemented on Windows"
@@ -51,14 +57,14 @@ module Bolt
51
57
  end
52
58
 
53
59
  def run_command(target, command, _options = {})
54
- in_tmpdir(target.options[:tmpdir]) do |_|
60
+ in_tmpdir(target.options['tmpdir']) do |_|
55
61
  output = @conn.execute(command, {})
56
62
  Bolt::Result.for_command(target, output.stdout.string, output.stderr.string, output.exit_code)
57
63
  end
58
64
  end
59
65
 
60
66
  def run_script(target, script, arguments, _options = {})
61
- with_tmpscript(File.absolute_path(script), target.options[:tmpdir]) do |file|
67
+ with_tmpscript(File.absolute_path(script), target.options['tmpdir']) do |file|
62
68
  logger.debug "Running '#{file}' with #{arguments}"
63
69
 
64
70
  if arguments.empty?
@@ -76,7 +82,7 @@ module Bolt
76
82
  stdin = STDIN_METHODS.include?(input_method) ? JSON.dump(arguments) : nil
77
83
  env = ENVIRONMENT_METHODS.include?(input_method) ? arguments : nil
78
84
 
79
- with_tmpscript(task.executable, target.options[:tmpdir]) do |script|
85
+ with_tmpscript(task.executable, target.options['tmpdir']) do |script|
80
86
  logger.debug("Running '#{script}' with #{arguments}")
81
87
 
82
88
  output = @conn.execute(script, stdin: stdin, env: env)
@@ -11,6 +11,17 @@ module Bolt
11
11
  CONF_FILE = File.expand_path('~/.puppetlabs/client-tools/orchestrator.conf')
12
12
  BOLT_MOCK_TASK = Struct.new(:name, :executable).new('bolt', 'bolt/tasks/init').freeze
13
13
 
14
+ def self.options
15
+ %w[service-url cacert token-file task-environment local-validation]
16
+ end
17
+
18
+ def self.validate(options)
19
+ validation_flag = options['local-validation']
20
+ unless !!validation_flag == validation_flag
21
+ raise Bolt::CLIError, 'local-validation option must be a Boolean true or false'
22
+ end
23
+ end
24
+
14
25
  def create_client(opts)
15
26
  client_keys = %i[service-url token-file cacert]
16
27
  client_opts = opts.reduce({}) do |acc, (k, v)|
@@ -20,14 +31,14 @@ module Bolt
20
31
  acc
21
32
  end
22
33
  end
23
- @logger.debug("Creating orchestrator client for #{client_opts}")
34
+ logger.debug("Creating orchestrator client for #{client_opts}")
24
35
 
25
36
  OrchestratorClient.new(client_opts, true)
26
37
  end
27
38
 
28
39
  def build_request(targets, task, arguments)
29
40
  { task: task.name,
30
- environment: targets.first.options[:"task-environment"],
41
+ environment: targets.first.options["task-environment"],
31
42
  noop: arguments['_noop'],
32
43
  params: arguments.reject { |k, _| k == '_noop' },
33
44
  scope: {
@@ -117,9 +128,9 @@ module Bolt
117
128
 
118
129
  def batches(targets)
119
130
  targets.group_by do |target|
120
- [target.options[:"task-environment"],
121
- target.options[:"service-url"],
122
- target.options[:"token-file"]]
131
+ [target.options['task-environment'],
132
+ target.options['service-url'],
133
+ target.options['token-file']]
123
134
  end.values
124
135
  end
125
136
 
@@ -6,7 +6,38 @@ require 'shellwords'
6
6
  module Bolt
7
7
  module Transport
8
8
  class SSH < Base
9
- def initialize(_config)
9
+ def self.options
10
+ %w[port user password sudo-password private-key host-key-check connect-timeout tmpdir run-as]
11
+ end
12
+
13
+ def self.validate(options)
14
+ logger = Logging.logger[self]
15
+
16
+ if options['sudo-password'] && options['run-as'].nil?
17
+ logger.warn("--sudo-password will not be used without specifying a " \
18
+ "user to escalate to with --run-as")
19
+ end
20
+
21
+ host_key = options['host-key-check']
22
+ unless !!host_key == host_key
23
+ raise Bolt::CLIError, 'host-key-check option must be a Boolean true or false'
24
+ end
25
+
26
+ if (key_opt = options['private-key'])
27
+ unless key_opt.instance_of?(String) || (key_opt.instance_of?(Hash) && key_opt.include?('key-data'))
28
+ raise Bolt::CLIError,
29
+ "private-key option must be the path to a private key file or a hash containing the 'key-data'"
30
+ end
31
+ end
32
+
33
+ timeout_value = options['connect-timeout']
34
+ unless timeout_value.is_a?(Integer) || timeout_value.nil?
35
+ error_msg = "connect-timeout value must be an Integer, received #{timeout_value}:#{timeout_value.class}"
36
+ raise Bolt::CLIError, error_msg
37
+ end
38
+ end
39
+
40
+ def initialize
10
41
  super
11
42
 
12
43
  require 'net/ssh'
@@ -68,15 +68,22 @@ module Bolt
68
68
  non_interactive: true
69
69
  }
70
70
 
71
+ if (key = target.options['private-key'])
72
+ if key.instance_of?(String)
73
+ options[:keys] = key
74
+ else
75
+ options[:key_data] = [key['key-data']]
76
+ end
77
+ end
78
+
71
79
  options[:port] = target.port if target.port
72
80
  options[:password] = target.password if target.password
73
- options[:keys] = target.options[:key] if target.options[:key]
74
- options[:verify_host_key] = if target.options[:host_key_check]
81
+ options[:verify_host_key] = if target.options['host-key-check']
75
82
  Net::SSH::Verifiers::Secure.new
76
83
  else
77
84
  Net::SSH::Verifiers::Lenient.new
78
85
  end
79
- options[:timeout] = target.options[:connect_timeout] if target.options[:connect_timeout]
86
+ options[:timeout] = target.options['connect-timeout'] if target.options['connect-timeout']
80
87
 
81
88
  # Mirroring:
82
89
  # https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/authentication/agent.rb#L80
@@ -108,7 +115,7 @@ module Bolt
108
115
  )
109
116
  rescue Net::SSH::ConnectionTimeout
110
117
  raise Bolt::Node::ConnectError.new(
111
- "Timeout after #{target.options[:connect_timeout]} seconds connecting to #{target.uri}",
118
+ "Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.uri}",
112
119
  'CONNECT_ERROR'
113
120
  )
114
121
  rescue StandardError => e
@@ -129,7 +136,7 @@ module Bolt
129
136
  # override for the user to run as. When @run_as is unset, the user
130
137
  # specified on the target will be used.
131
138
  def run_as
132
- @run_as || target.options[:run_as]
139
+ @run_as || target.options['run-as']
133
140
  end
134
141
 
135
142
  # Run as the specified user for the duration of the block.
@@ -146,8 +153,8 @@ module Bolt
146
153
 
147
154
  def handled_sudo(channel, data)
148
155
  if data.lines.include?(sudo_prompt)
149
- if target.options[:sudo_password]
150
- channel.send_data "#{target.options[:sudo_password]}\n"
156
+ if target.options['sudo-password']
157
+ channel.send_data "#{target.options['sudo-password']}\n"
151
158
  channel.wait
152
159
  return true
153
160
  else
@@ -196,7 +203,7 @@ module Bolt
196
203
 
197
204
  session_channel = @session.open_channel do |channel|
198
205
  # Request a pseudo tty
199
- channel.request_pty if target.options[:tty]
206
+ channel.request_pty if target.options['tty']
200
207
 
201
208
  channel.exec(command_str) do |_, success|
202
209
  unless success
@@ -247,8 +254,8 @@ module Bolt
247
254
  end
248
255
 
249
256
  def make_tempdir
250
- if target.options[:tmpdir]
251
- tmppath = "#{target.options[:tmpdir]}/#{SecureRandom.uuid}"
257
+ if target.options['tmpdir']
258
+ tmppath = "#{target.options['tmpdir']}/#{SecureRandom.uuid}"
252
259
  command = ['mkdir', '-m', 700, tmppath]
253
260
  else
254
261
  command = ['mktemp', '-d']