puppet 6.13.0 → 6.14.0

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

Potentially problematic release.


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

Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +7 -13
  3. data/Gemfile.lock +6 -6
  4. data/README.md +15 -22
  5. data/lib/puppet.rb +1 -1
  6. data/lib/puppet/application/agent.rb +9 -11
  7. data/lib/puppet/application/describe.rb +7 -5
  8. data/lib/puppet/application/device.rb +2 -2
  9. data/lib/puppet/application/filebucket.rb +14 -1
  10. data/lib/puppet/application/ssl.rb +1 -1
  11. data/lib/puppet/configurer.rb +30 -41
  12. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  13. data/lib/puppet/defaults.rb +7 -1
  14. data/lib/puppet/face/plugin.rb +1 -1
  15. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  16. data/lib/puppet/http.rb +1 -0
  17. data/lib/puppet/http/client.rb +69 -34
  18. data/lib/puppet/http/resolver/server_list.rb +2 -2
  19. data/lib/puppet/http/resolver/settings.rb +1 -1
  20. data/lib/puppet/http/resolver/srv.rb +1 -1
  21. data/lib/puppet/http/response.rb +6 -1
  22. data/lib/puppet/http/service.rb +30 -11
  23. data/lib/puppet/http/service/ca.rb +8 -8
  24. data/lib/puppet/http/service/compiler.rb +41 -10
  25. data/lib/puppet/http/service/file_server.rb +40 -20
  26. data/lib/puppet/http/service/report.rb +12 -15
  27. data/lib/puppet/http/session.rb +39 -1
  28. data/lib/puppet/indirector/catalog/rest.rb +33 -0
  29. data/lib/puppet/indirector/facts/rest.rb +41 -0
  30. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  31. data/lib/puppet/indirector/file_metadata/rest.rb +50 -0
  32. data/lib/puppet/indirector/node/rest.rb +23 -0
  33. data/lib/puppet/indirector/report/rest.rb +19 -0
  34. data/lib/puppet/indirector/rest.rb +6 -0
  35. data/lib/puppet/indirector/status/rest.rb +17 -0
  36. data/lib/puppet/loaders.rb +6 -0
  37. data/lib/puppet/network/http/base_pool.rb +1 -1
  38. data/lib/puppet/network/http/pool.rb +6 -1
  39. data/lib/puppet/provider/group/groupadd.rb +9 -4
  40. data/lib/puppet/runtime.rb +8 -1
  41. data/lib/puppet/settings.rb +2 -0
  42. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  43. data/lib/puppet/ssl/state_machine.rb +4 -0
  44. data/lib/puppet/test/test_helper.rb +3 -1
  45. data/lib/puppet/type/file.rb +13 -0
  46. data/lib/puppet/type/file/source.rb +47 -58
  47. data/lib/puppet/version.rb +1 -1
  48. data/locales/puppet.pot +167 -160
  49. data/man/man5/puppet.conf.5 +11 -3
  50. data/man/man8/puppet-agent.8 +6 -6
  51. data/man/man8/puppet-apply.8 +1 -1
  52. data/man/man8/puppet-catalog.8 +1 -1
  53. data/man/man8/puppet-config.8 +1 -1
  54. data/man/man8/puppet-describe.8 +1 -1
  55. data/man/man8/puppet-device.8 +2 -2
  56. data/man/man8/puppet-doc.8 +1 -1
  57. data/man/man8/puppet-epp.8 +1 -1
  58. data/man/man8/puppet-facts.8 +1 -1
  59. data/man/man8/puppet-filebucket.8 +17 -2
  60. data/man/man8/puppet-generate.8 +1 -1
  61. data/man/man8/puppet-help.8 +1 -1
  62. data/man/man8/puppet-key.8 +1 -1
  63. data/man/man8/puppet-lookup.8 +1 -1
  64. data/man/man8/puppet-man.8 +1 -1
  65. data/man/man8/puppet-module.8 +1 -1
  66. data/man/man8/puppet-node.8 +1 -1
  67. data/man/man8/puppet-parser.8 +1 -1
  68. data/man/man8/puppet-plugin.8 +1 -1
  69. data/man/man8/puppet-report.8 +1 -1
  70. data/man/man8/puppet-resource.8 +1 -1
  71. data/man/man8/puppet-script.8 +1 -1
  72. data/man/man8/puppet-ssl.8 +2 -2
  73. data/man/man8/puppet-status.8 +1 -1
  74. data/man/man8/puppet.8 +2 -2
  75. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -67
  76. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -69
  77. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -69
  78. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -67
  79. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -65
  80. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -67
  81. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -67
  82. data/spec/integration/faces/plugin_spec.rb +3 -1
  83. data/spec/integration/http/client_spec.rb +11 -0
  84. data/spec/integration/network/http_pool_spec.rb +9 -1
  85. data/spec/unit/application/describe_spec.rb +88 -50
  86. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  87. data/spec/unit/configurer_spec.rb +16 -14
  88. data/spec/unit/face/plugin_spec.rb +12 -10
  89. data/spec/unit/functions/lookup_spec.rb +13 -0
  90. data/spec/unit/http/client_spec.rb +172 -1
  91. data/spec/unit/http/resolver_spec.rb +14 -2
  92. data/spec/unit/http/response_spec.rb +69 -0
  93. data/spec/unit/http/service/ca_spec.rb +28 -9
  94. data/spec/unit/http/service/compiler_spec.rb +151 -24
  95. data/spec/unit/http/service/file_server_spec.rb +65 -8
  96. data/spec/unit/http/service/report_spec.rb +17 -8
  97. data/spec/unit/http/service_spec.rb +92 -3
  98. data/spec/unit/http/session_spec.rb +104 -1
  99. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  100. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  101. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  102. data/spec/unit/indirector/file_metadata/rest_spec.rb +109 -2
  103. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  104. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  105. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  106. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  107. data/spec/unit/network/http/pool_spec.rb +57 -11
  108. data/spec/unit/provider/group/groupadd_spec.rb +22 -8
  109. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  110. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  111. data/spec/unit/ssl/state_machine_spec.rb +10 -0
  112. data/spec/unit/transaction_spec.rb +0 -2
  113. data/spec/unit/type/file/ensure_spec.rb +1 -2
  114. data/spec/unit/type/file/source_spec.rb +86 -35
  115. data/spec/unit/util/at_fork_spec.rb +1 -0
  116. data/spec/unit/util/pidlock_spec.rb +36 -24
  117. metadata +7 -3
  118. data/COMMITTERS.md +0 -244
@@ -2,9 +2,9 @@ class Puppet::HTTP::Service::Ca < Puppet::HTTP::Service
2
2
  HEADERS = { 'Accept' => 'text/plain' }.freeze
3
3
  API = '/puppet-ca/v1'.freeze
4
4
 
5
- def initialize(client, server, port)
5
+ def initialize(client, session, server, port)
6
6
  url = build_url(API, server || Puppet[:ca_server], port || Puppet[:ca_port])
7
- super(client, url)
7
+ super(client, session, url)
8
8
  end
9
9
 
10
10
  def get_certificate(name, ssl_context: nil)
@@ -14,9 +14,9 @@ class Puppet::HTTP::Service::Ca < Puppet::HTTP::Service
14
14
  ssl_context: ssl_context
15
15
  )
16
16
 
17
- return response.body.to_s if response.success?
17
+ process_response(response)
18
18
 
19
- raise Puppet::HTTP::ResponseError.new(response)
19
+ response.body.to_s
20
20
  end
21
21
 
22
22
  def get_certificate_revocation_list(if_modified_since: nil, ssl_context: nil)
@@ -29,9 +29,9 @@ class Puppet::HTTP::Service::Ca < Puppet::HTTP::Service
29
29
  ssl_context: ssl_context
30
30
  )
31
31
 
32
- return response.body.to_s if response.success?
32
+ process_response(response)
33
33
 
34
- raise Puppet::HTTP::ResponseError.new(response)
34
+ response.body.to_s
35
35
  end
36
36
 
37
37
  def put_certificate_request(name, csr, ssl_context: nil)
@@ -43,8 +43,8 @@ class Puppet::HTTP::Service::Ca < Puppet::HTTP::Service
43
43
  ssl_context: ssl_context
44
44
  )
45
45
 
46
- return response.body.to_s if response.success?
46
+ process_response(response)
47
47
 
48
- raise Puppet::HTTP::ResponseError.new(response)
48
+ response.body.to_s
49
49
  end
50
50
  end
@@ -1,9 +1,9 @@
1
1
  class Puppet::HTTP::Service::Compiler < Puppet::HTTP::Service
2
2
  API = '/puppet/v3'.freeze
3
3
 
4
- def initialize(client, server, port)
4
+ def initialize(client, session, server, port)
5
5
  url = build_url(API, server || Puppet[:server], port || Puppet[:masterport])
6
- super(client, url)
6
+ super(client, session, url)
7
7
  end
8
8
 
9
9
  def get_node(name, environment:, configured_environment: nil, transaction_uuid: nil)
@@ -16,15 +16,15 @@ class Puppet::HTTP::Service::Compiler < Puppet::HTTP::Service
16
16
  environment: environment,
17
17
  configured_environment: configured_environment || environment,
18
18
  transaction_uuid: transaction_uuid,
19
- },
19
+ }
20
20
  )
21
21
 
22
- return deserialize(response, Puppet::Node) if response.success?
22
+ process_response(response)
23
23
 
24
- raise Puppet::HTTP::ResponseError.new(response)
24
+ deserialize(response, Puppet::Node)
25
25
  end
26
26
 
27
- def get_catalog(name, facts:, environment:, configured_environment: nil, transaction_uuid: nil, job_uuid: nil, static_catalog: true, checksum_type: Puppet[:supported_checksum_types])
27
+ def post_catalog(name, facts:, environment:, configured_environment: nil, transaction_uuid: nil, job_uuid: nil, static_catalog: true, checksum_type: Puppet[:supported_checksum_types])
28
28
  if Puppet[:preferred_serialization_format] == "pson"
29
29
  formatter = Puppet::Network::FormatHandler.format_for(:pson)
30
30
  # must use 'pson' instead of 'text/pson'
@@ -61,9 +61,23 @@ class Puppet::HTTP::Service::Compiler < Puppet::HTTP::Service
61
61
  body: body,
62
62
  )
63
63
 
64
- return deserialize(response, Puppet::Resource::Catalog) if response.success?
64
+ process_response(response)
65
+
66
+ deserialize(response, Puppet::Resource::Catalog)
67
+ end
68
+
69
+ def get_facts(name, environment:)
70
+ headers = add_puppet_headers('Accept' => get_mime_types(Puppet::Node::Facts).join(', '))
71
+
72
+ response = @client.get(
73
+ with_base_url("/facts/#{name}"),
74
+ headers: headers,
75
+ params: { environment: environment }
76
+ )
77
+
78
+ process_response(response)
65
79
 
66
- raise Puppet::HTTP::ResponseError.new(response)
80
+ deserialize(response, Puppet::Node::Facts)
67
81
  end
68
82
 
69
83
  def put_facts(name, environment:, facts:)
@@ -79,8 +93,25 @@ class Puppet::HTTP::Service::Compiler < Puppet::HTTP::Service
79
93
  body: serialize(formatter, facts),
80
94
  )
81
95
 
82
- return true if response.success?
96
+ process_response(response)
97
+
98
+ true
99
+ end
100
+
101
+ def get_status(name)
102
+ headers = add_puppet_headers('Accept' => get_mime_types(Puppet::Status).join(', '))
103
+
104
+ response = @client.get(
105
+ with_base_url("/status/#{name}"),
106
+ headers: headers,
107
+ params: {
108
+ # environment is required, but meaningless, default to production
109
+ environment: 'production'
110
+ },
111
+ )
112
+
113
+ process_response(response)
83
114
 
84
- raise Puppet::HTTP::ResponseError.new(response)
115
+ deserialize(response, Puppet::Status)
85
116
  end
86
117
  end
@@ -4,15 +4,15 @@ class Puppet::HTTP::Service::FileServer < Puppet::HTTP::Service
4
4
  API = '/puppet/v3'.freeze
5
5
  PATH_REGEX = /^\//
6
6
 
7
- def initialize(client, server, port)
7
+ def initialize(client, session, server, port)
8
8
  url = build_url(API, server || Puppet[:server], port || Puppet[:masterport])
9
- super(client, url)
9
+ super(client, session, url)
10
10
  end
11
11
 
12
- def get_file_metadata(path:, environment:, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore, ssl_context: nil)
12
+ def get_file_metadata(path:, environment:, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore)
13
13
  validate_path(path)
14
14
 
15
- headers = add_puppet_headers({ 'Accept' => get_mime_types(Puppet::FileServing::Metadata).join(', ') })
15
+ headers = add_puppet_headers('Accept' => get_mime_types(Puppet::FileServing::Metadata).join(', '))
16
16
 
17
17
  response = @client.get(
18
18
  with_base_url("/file_metadata#{path}"),
@@ -22,19 +22,18 @@ class Puppet::HTTP::Service::FileServer < Puppet::HTTP::Service
22
22
  checksum_type: checksum_type,
23
23
  source_permissions: source_permissions,
24
24
  environment: environment
25
- },
26
- ssl_context: ssl_context
25
+ }
27
26
  )
28
27
 
29
- return deserialize(response, Puppet::FileServing::Metadata) if response.success?
28
+ process_response(response)
30
29
 
31
- raise Puppet::HTTP::ResponseError.new(response)
30
+ deserialize(response, Puppet::FileServing::Metadata)
32
31
  end
33
32
 
34
- def get_file_metadatas(path: nil, environment:, recurse: :false, recurselimit: nil, ignore: nil, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore, ssl_context: nil)
33
+ def get_file_metadatas(path: nil, environment:, recurse: :false, recurselimit: nil, ignore: nil, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore)
35
34
  validate_path(path)
36
35
 
37
- headers = add_puppet_headers({ 'Accept' => get_mime_types(Puppet::FileServing::Metadata).join(', ') })
36
+ headers = add_puppet_headers('Accept' => get_mime_types(Puppet::FileServing::Metadata).join(', '))
38
37
 
39
38
  response = @client.get(
40
39
  with_base_url("/file_metadatas#{path}"),
@@ -47,36 +46,57 @@ class Puppet::HTTP::Service::FileServer < Puppet::HTTP::Service
47
46
  checksum_type: checksum_type,
48
47
  source_permissions: source_permissions,
49
48
  environment: environment,
50
- },
51
- ssl_context: ssl_context
49
+ }
52
50
  )
53
51
 
54
- return deserialize_multiple(response, Puppet::FileServing::Metadata) if response.success?
52
+ process_response(response)
55
53
 
56
- raise Puppet::HTTP::ResponseError.new(response)
54
+ deserialize_multiple(response, Puppet::FileServing::Metadata)
57
55
  end
58
56
 
59
- def get_file_content(path:, environment:, ssl_context: nil, &block)
57
+ def get_file_content(path:, environment:, &block)
60
58
  validate_path(path)
61
59
 
62
- headers = add_puppet_headers({'Accept' => 'application/octet-stream' })
60
+ headers = add_puppet_headers('Accept' => 'application/octet-stream')
63
61
  response = @client.get(
64
62
  with_base_url("/file_content#{path}"),
65
63
  headers: headers,
66
64
  params: {
67
65
  environment: environment
68
- },
69
- ssl_context: ssl_context
66
+ }
70
67
  ) do |res|
71
68
  if res.success?
72
69
  res.read_body(&block)
73
70
  end
74
71
  end
75
72
 
76
- return nil if response.success?
73
+ process_response(response)
77
74
 
78
- raise Puppet::HTTP::ResponseError.new(response)
75
+ nil
79
76
  end
77
+
78
+ def get_static_file_content(path:, environment:, code_id:, &block)
79
+ validate_path(path)
80
+
81
+ headers = add_puppet_headers('Accept' => 'application/octet-stream')
82
+ response = @client.get(
83
+ with_base_url("/static_file_content#{path}"),
84
+ headers: headers,
85
+ params: {
86
+ environment: environment,
87
+ code_id: code_id,
88
+ }
89
+ ) do |res|
90
+ if res.success?
91
+ res.read_body(&block)
92
+ end
93
+ end
94
+
95
+ process_response(response)
96
+
97
+ nil
98
+ end
99
+
80
100
  private
81
101
 
82
102
  def validate_path(path)
@@ -1,15 +1,12 @@
1
1
  class Puppet::HTTP::Service::Report < Puppet::HTTP::Service
2
2
  API = '/puppet/v3'.freeze
3
3
 
4
- # puppet major version where JSON is enabled by default
5
- MAJOR_VERSION_JSON_DEFAULT = 5
6
-
7
- def initialize(client, server, port)
4
+ def initialize(client, session, server, port)
8
5
  url = build_url(API, server || Puppet[:report_server], port || Puppet[:report_port])
9
- super(client, url)
6
+ super(client, session, url)
10
7
  end
11
8
 
12
- def put_report(name, report, environment:, ssl_context: nil)
9
+ def put_report(name, report, environment:)
13
10
  formatter = Puppet::Network::FormatHandler.format_for(Puppet[:preferred_serialization_format])
14
11
  headers = add_puppet_headers('Accept' => get_mime_types(Puppet::Transaction::Report).join(', '))
15
12
 
@@ -18,19 +15,19 @@ class Puppet::HTTP::Service::Report < Puppet::HTTP::Service
18
15
  headers: headers,
19
16
  params: { environment: environment },
20
17
  content_type: formatter.mime,
21
- body: serialize(formatter, report),
22
- ssl_context: ssl_context
18
+ body: serialize(formatter, report)
23
19
  )
24
20
 
25
- return response.body.to_s if response.success?
21
+ # override parent's process_response handling
22
+ @session.process_response(response)
26
23
 
27
- server_version = response[Puppet::Network::HTTP::HEADER_PUPPET_VERSION]
28
- if server_version && SemanticPuppet::Version.parse(server_version).major < MAJOR_VERSION_JSON_DEFAULT &&
29
- Puppet[:preferred_serialization_format] != 'pson'
24
+ if response.success?
25
+ response
26
+ elsif !@session.supports?(:report, 'json') && Puppet[:preferred_serialization_format] != 'pson'
30
27
  #TRANSLATORS "pson", "preferred_serialization_format", and "puppetserver" should not be translated
31
- raise Puppet::HTTP::ProtocolError.new(_("To submit reports to a server running puppetserver %{server_version}, set preferred_serialization_format to pson") % { server_version: server_version })
28
+ raise Puppet::HTTP::ProtocolError.new(_("To submit reports to a server running puppetserver %{server_version}, set preferred_serialization_format to pson") % { server_version: response[Puppet::HTTP::HEADER_PUPPET_VERSION]})
29
+ else
30
+ raise Puppet::HTTP::ResponseError.new(response)
32
31
  end
33
-
34
- raise Puppet::HTTP::ResponseError.new(response)
35
32
  end
36
33
  end
@@ -1,9 +1,20 @@
1
1
  class Puppet::HTTP::Session
2
+ # capabilities for a site
3
+ CAP_LOCALES = 'locales'.freeze
4
+ CAP_JSON = 'json'.freeze
5
+
6
+ # puppet version where locales mount was added
7
+ SUPPORTED_LOCALES_MOUNT_AGENT_VERSION = Gem::Version.new("5.3.4")
8
+
9
+ # puppet version where JSON was enabled by default
10
+ SUPPORTED_JSON_DEFAULT = Gem::Version.new("5.0.0")
11
+
2
12
  def initialize(client, resolvers)
3
13
  @client = client
4
14
  @resolvers = resolvers
5
15
  @resolved_services = {}
6
16
  @resolution_exceptions = []
17
+ @server_versions = {}
7
18
  end
8
19
 
9
20
  def route_to(name, url: nil, ssl_context: nil)
@@ -11,7 +22,7 @@ class Puppet::HTTP::Session
11
22
 
12
23
  # short circuit if explicit URL host & port given
13
24
  if url && url.host != nil && !url.host.empty?
14
- service = Puppet::HTTP::Service.create_service(@client, name, url.host, url.port)
25
+ service = Puppet::HTTP::Service.create_service(@client, self, name, url.host, url.port)
15
26
  service.connect(ssl_context: ssl_context)
16
27
  return service
17
28
  end
@@ -38,4 +49,31 @@ class Puppet::HTTP::Session
38
49
  def add_exception(exception)
39
50
  @resolution_exceptions << exception
40
51
  end
52
+
53
+ def process_response(response)
54
+ version = response[Puppet::HTTP::HEADER_PUPPET_VERSION]
55
+ if version
56
+ site = Puppet::Network::HTTP::Site.from_uri(response.url)
57
+ @server_versions[site] = version
58
+ end
59
+ end
60
+
61
+ def supports?(name, capability)
62
+ raise ArgumentError, "Unknown service #{name}" unless Puppet::HTTP::Service.valid_name?(name)
63
+
64
+ service = @resolved_services[name]
65
+ return false unless service
66
+
67
+ site = Puppet::Network::HTTP::Site.from_uri(service.url)
68
+ server_version = @server_versions[site]
69
+
70
+ case capability
71
+ when CAP_LOCALES
72
+ !server_version.nil? && Gem::Version.new(server_version) >= SUPPORTED_LOCALES_MOUNT_AGENT_VERSION
73
+ when CAP_JSON
74
+ server_version.nil? || Gem::Version.new(server_version) >= SUPPORTED_JSON_DEFAULT
75
+ else
76
+ false
77
+ end
78
+ end
41
79
  end
@@ -3,4 +3,37 @@ require 'puppet/indirector/rest'
3
3
 
4
4
  class Puppet::Resource::Catalog::Rest < Puppet::Indirector::REST
5
5
  desc "Find resource catalogs over HTTP via REST."
6
+
7
+ def find(request)
8
+ return super unless use_http_client?
9
+
10
+ checksum_type = if request.options[:checksum_type]
11
+ request.options[:checksum_type].split('.')
12
+ else
13
+ Puppet[:supported_checksum_types]
14
+ end
15
+
16
+ session = Puppet.lookup(:http_session)
17
+ api = session.route_to(:puppet)
18
+ api.post_catalog(
19
+ request.key,
20
+ facts: request.options[:facts_for_catalog],
21
+ environment: request.environment.to_s,
22
+ configured_environment: request.options[:configured_environment],
23
+ transaction_uuid: request.options[:transaction_uuid],
24
+ job_uuid: request.options[:job_id],
25
+ static_catalog: request.options[:static_catalog],
26
+ checksum_type: checksum_type
27
+ )
28
+ rescue Puppet::HTTP::ResponseError => e
29
+ if e.response.code == 404
30
+ return nil unless request.options[:fail_on_404]
31
+
32
+ _, body = parse_response(e.response.nethttp)
33
+ msg = _("Find %{uri} resulted in 404 with the message: %{body}") % { uri: elide(e.response.url.path, 100), body: body }
34
+ raise Puppet::Error, msg
35
+ else
36
+ raise convert_to_http_error(e.response.nethttp)
37
+ end
38
+ end
6
39
  end
@@ -4,9 +4,50 @@ require 'puppet/indirector/rest'
4
4
  class Puppet::Node::Facts::Rest < Puppet::Indirector::REST
5
5
  desc "Find and save facts about nodes over HTTP via REST."
6
6
 
7
+ def find(request)
8
+ return super unless use_http_client?
9
+
10
+ session = Puppet.lookup(:http_session)
11
+ api = session.route_to(:puppet)
12
+ api.get_facts(
13
+ request.key,
14
+ environment: request.environment.to_s
15
+ )
16
+ rescue Puppet::HTTP::ResponseError => e
17
+ if e.response.code == 404
18
+ return nil unless request.options[:fail_on_404]
19
+
20
+ _, body = parse_response(e.response.nethttp)
21
+ msg = _("Find %{uri} resulted in 404 with the message: %{body}") % { uri: elide(e.response.url.path, 100), body: body }
22
+ raise Puppet::Error, msg
23
+ else
24
+ raise convert_to_http_error(e.response.nethttp)
25
+ end
26
+ end
27
+
7
28
  def save(request)
8
29
  raise ArgumentError, _("PUT does not accept options") unless request.options.empty?
9
30
 
31
+ return legacy_save(request) unless use_http_client?
32
+
33
+ session = Puppet.lookup(:http_session)
34
+ api = session.route_to(:puppet)
35
+ api.put_facts(
36
+ request.key,
37
+ facts: request.instance,
38
+ environment: request.environment.to_s
39
+ )
40
+
41
+ # preserve existing behavior
42
+ nil
43
+ rescue Puppet::HTTP::ResponseError => e
44
+ # always raise even if fail_on_404 is false
45
+ raise convert_to_http_error(e.response.nethttp)
46
+ end
47
+
48
+ private
49
+
50
+ def legacy_save(request)
10
51
  response = do_request(request) do |req|
11
52
  http_put(req, IndirectedRoutes.request_to_uri(req), req.instance.render, headers.merge({ "Content-Type" => req.instance.mime }))
12
53
  end
@@ -6,4 +6,34 @@ class Puppet::Indirector::FileContent::Rest < Puppet::Indirector::REST
6
6
  desc "Retrieve file contents via a REST HTTP interface."
7
7
 
8
8
  use_srv_service(:fileserver)
9
+
10
+ def find(request)
11
+ return super unless use_http_client?
12
+
13
+ content = StringIO.new
14
+ content.binmode
15
+
16
+ url = URI.parse(Puppet::Util.uri_encode(request.uri))
17
+ session = Puppet.lookup(:http_session)
18
+ api = session.route_to(:fileserver, url: url)
19
+
20
+ api.get_file_content(
21
+ path: URI.unescape(url.path),
22
+ environment: request.environment.to_s,
23
+ ) do |data|
24
+ content << data
25
+ end
26
+
27
+ Puppet::FileServing::Content.from_binary(content.string)
28
+ rescue Puppet::HTTP::ResponseError => e
29
+ if e.response.code == 404
30
+ return nil unless request.options[:fail_on_404]
31
+
32
+ _, body = parse_response(e.response.nethttp)
33
+ msg = _("Find %{uri} resulted in 404 with the message: %{body}") % { uri: elide(e.response.url.path, 100), body: body }
34
+ raise Puppet::Error, msg
35
+ else
36
+ raise convert_to_http_error(e.response.nethttp)
37
+ end
38
+ end
9
39
  end