puppet 6.3.0-universal-darwin → 6.4.0-universal-darwin

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +30 -0
  3. data/Gemfile.lock +9 -9
  4. data/lib/puppet.rb +13 -0
  5. data/lib/puppet/application/agent.rb +8 -12
  6. data/lib/puppet/application/device.rb +2 -3
  7. data/lib/puppet/application/filebucket.rb +6 -1
  8. data/lib/puppet/application/ssl.rb +102 -55
  9. data/lib/puppet/configurer.rb +8 -7
  10. data/lib/puppet/defaults.rb +3 -1
  11. data/lib/puppet/file_system.rb +24 -4
  12. data/lib/puppet/file_system/file_impl.rb +25 -0
  13. data/lib/puppet/file_system/jruby.rb +23 -0
  14. data/lib/puppet/file_system/windows.rb +84 -0
  15. data/lib/puppet/indirector/rest.rb +4 -2
  16. data/lib/puppet/loaders.rb +1 -0
  17. data/lib/puppet/network/http.rb +1 -0
  18. data/lib/puppet/network/http/base_pool.rb +18 -0
  19. data/lib/puppet/network/http/connection.rb +49 -17
  20. data/lib/puppet/network/http/nocache_pool.rb +9 -4
  21. data/lib/puppet/network/http/pool.rb +10 -11
  22. data/lib/puppet/network/http/session.rb +3 -2
  23. data/lib/puppet/network/http_pool.rb +32 -0
  24. data/lib/puppet/pops/loader/generic_plan_instantiator.rb +28 -0
  25. data/lib/puppet/pops/loader/loader_paths.rb +46 -10
  26. data/lib/puppet/pops/loader/module_loaders.rb +10 -3
  27. data/lib/puppet/provider/file/windows.rb +49 -1
  28. data/lib/puppet/provider/package/windows.rb +5 -1
  29. data/lib/puppet/reports/http.rb +2 -1
  30. data/lib/puppet/rest/client.rb +7 -3
  31. data/lib/puppet/rest/routes.rb +9 -44
  32. data/lib/puppet/ssl.rb +6 -0
  33. data/lib/puppet/ssl/error.rb +26 -0
  34. data/lib/puppet/ssl/host.rb +9 -92
  35. data/lib/puppet/ssl/ssl_context.rb +30 -0
  36. data/lib/puppet/ssl/ssl_provider.rb +232 -0
  37. data/lib/puppet/ssl/state_machine.rb +261 -0
  38. data/lib/puppet/ssl/validator.rb +1 -0
  39. data/lib/puppet/ssl/validator/default_validator.rb +1 -0
  40. data/lib/puppet/ssl/validator/no_validator.rb +2 -0
  41. data/lib/puppet/ssl/verifier.rb +134 -0
  42. data/lib/puppet/ssl/verifier_adapter.rb +48 -0
  43. data/lib/puppet/test/test_helper.rb +2 -1
  44. data/lib/puppet/type/exec.rb +30 -6
  45. data/lib/puppet/type/file/mode.rb +6 -1
  46. data/lib/puppet/type/file/source.rb +2 -2
  47. data/lib/puppet/type/filebucket.rb +12 -8
  48. data/lib/puppet/type/user.rb +14 -1
  49. data/lib/puppet/util/connection.rb +10 -5
  50. data/lib/puppet/util/feature.rb +11 -2
  51. data/lib/puppet/util/http_proxy.rb +3 -2
  52. data/lib/puppet/util/pidlock.rb +1 -1
  53. data/lib/puppet/util/ssl.rb +1 -10
  54. data/lib/puppet/util/windows/security.rb +29 -8
  55. data/lib/puppet/version.rb +1 -1
  56. data/lib/puppet/x509.rb +7 -0
  57. data/lib/puppet/x509/cert_provider.rb +286 -0
  58. data/lib/puppet/x509/pem_store.rb +55 -0
  59. data/locales/ja/puppet.po +740 -590
  60. data/locales/puppet.pot +433 -208
  61. data/man/man5/puppet.conf.5 +6 -3
  62. data/man/man8/puppet-agent.8 +1 -1
  63. data/man/man8/puppet-apply.8 +1 -1
  64. data/man/man8/puppet-catalog.8 +1 -1
  65. data/man/man8/puppet-config.8 +1 -1
  66. data/man/man8/puppet-describe.8 +1 -1
  67. data/man/man8/puppet-device.8 +1 -1
  68. data/man/man8/puppet-doc.8 +1 -1
  69. data/man/man8/puppet-epp.8 +1 -1
  70. data/man/man8/puppet-facts.8 +1 -1
  71. data/man/man8/puppet-filebucket.8 +6 -2
  72. data/man/man8/puppet-generate.8 +1 -1
  73. data/man/man8/puppet-help.8 +1 -1
  74. data/man/man8/puppet-key.8 +1 -1
  75. data/man/man8/puppet-lookup.8 +1 -1
  76. data/man/man8/puppet-man.8 +1 -1
  77. data/man/man8/puppet-module.8 +1 -1
  78. data/man/man8/puppet-node.8 +1 -1
  79. data/man/man8/puppet-parser.8 +1 -1
  80. data/man/man8/puppet-plugin.8 +1 -1
  81. data/man/man8/puppet-report.8 +1 -1
  82. data/man/man8/puppet-resource.8 +1 -1
  83. data/man/man8/puppet-script.8 +1 -1
  84. data/man/man8/puppet-ssl.8 +5 -1
  85. data/man/man8/puppet-status.8 +1 -1
  86. data/man/man8/puppet.8 +2 -2
  87. data/spec/fixtures/ssl/127.0.0.1-key.pem +67 -0
  88. data/spec/fixtures/ssl/127.0.0.1.pem +48 -0
  89. data/spec/fixtures/ssl/bad-basic-constraints.pem +59 -0
  90. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +59 -0
  91. data/spec/fixtures/ssl/ca.pem +59 -0
  92. data/spec/fixtures/ssl/crl.pem +30 -0
  93. data/spec/fixtures/ssl/encrypted-key.pem +70 -0
  94. data/spec/fixtures/ssl/intermediate-agent-crl.pem +31 -0
  95. data/spec/fixtures/ssl/intermediate-agent.pem +60 -0
  96. data/spec/fixtures/ssl/intermediate-crl.pem +36 -0
  97. data/spec/fixtures/ssl/intermediate.pem +60 -0
  98. data/spec/fixtures/ssl/netlock-arany-utf8.pem +23 -0
  99. data/spec/fixtures/ssl/pluto-key.pem +67 -0
  100. data/spec/fixtures/ssl/pluto.pem +44 -0
  101. data/spec/fixtures/ssl/request-key.pem +67 -0
  102. data/spec/fixtures/ssl/request.pem +39 -0
  103. data/spec/fixtures/ssl/revoked-key.pem +67 -0
  104. data/spec/fixtures/ssl/revoked.pem +44 -0
  105. data/spec/fixtures/ssl/signed-key.pem +67 -0
  106. data/spec/fixtures/ssl/signed.pem +44 -0
  107. data/spec/fixtures/ssl/tampered-cert.pem +44 -0
  108. data/spec/fixtures/ssl/tampered-csr.pem +39 -0
  109. data/spec/integration/network/http_pool_spec.rb +222 -0
  110. data/spec/integration/provider/file/windows_spec.rb +162 -0
  111. data/spec/integration/rest/client_spec.rb +73 -0
  112. data/spec/integration/type/file_spec.rb +0 -19
  113. data/spec/lib/puppet/test_ca.rb +87 -50
  114. data/spec/lib/puppet_spec/fixtures.rb +20 -0
  115. data/spec/lib/puppet_spec/https.rb +84 -0
  116. data/spec/unit/application/agent_spec.rb +29 -30
  117. data/spec/unit/application/device_spec.rb +12 -49
  118. data/spec/unit/application/ssl_spec.rb +24 -38
  119. data/spec/unit/configurer_spec.rb +11 -11
  120. data/spec/unit/file_system/uniquefile_spec.rb +6 -0
  121. data/spec/unit/file_system_spec.rb +214 -0
  122. data/spec/unit/indirector/rest_spec.rb +3 -3
  123. data/spec/unit/network/http/connection_spec.rb +30 -90
  124. data/spec/unit/network/http/factory_spec.rb +1 -0
  125. data/spec/unit/network/http/nocache_pool_spec.rb +8 -8
  126. data/spec/unit/network/http/pool_spec.rb +63 -33
  127. data/spec/unit/network/http/session_spec.rb +8 -1
  128. data/spec/unit/network/http_pool_spec.rb +36 -0
  129. data/spec/unit/pops/loaders/loader_spec.rb +26 -1
  130. data/spec/unit/provider/package/windows_spec.rb +12 -1
  131. data/spec/unit/reports/http_spec.rb +7 -7
  132. data/spec/unit/rest/client_spec.rb +4 -6
  133. data/spec/unit/ssl/host_spec.rb +39 -33
  134. data/spec/unit/ssl/ssl_provider_spec.rb +428 -0
  135. data/spec/unit/ssl/state_machine_spec.rb +502 -0
  136. data/spec/unit/ssl/verifier_spec.rb +123 -0
  137. data/spec/unit/type/exec_spec.rb +63 -0
  138. data/spec/unit/type/file/source_spec.rb +5 -5
  139. data/spec/unit/type/filebucket_spec.rb +8 -6
  140. data/spec/unit/util/feature_spec.rb +2 -2
  141. data/spec/unit/util/storage_spec.rb +19 -19
  142. data/spec/unit/x509/cert_provider_spec.rb +527 -0
  143. data/spec/unit/x509/pem_store_spec.rb +160 -0
  144. data/tasks/generate_cert_fixtures.rake +158 -0
  145. metadata +78 -4
  146. data/MAINTAINERS +0 -47
  147. data/lib/puppet/rest/ssl_context.rb +0 -13
@@ -2,6 +2,7 @@ require 'openssl'
2
2
 
3
3
  # API for certificate verification
4
4
  #
5
+ # @deprecated
5
6
  # @api public
6
7
  class Puppet::SSL::Validator
7
8
 
@@ -4,6 +4,7 @@ require 'puppet/ssl'
4
4
  # Perform peer certificate verification against the known CA.
5
5
  # If there is no CA information known, then no verification is performed
6
6
  #
7
+ # @deprecated
7
8
  # @api private
8
9
  #
9
10
  class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
@@ -2,6 +2,8 @@ require 'openssl'
2
2
  require 'puppet/ssl'
3
3
 
4
4
  # Performs no SSL verification
5
+ #
6
+ # @deprecated
5
7
  # @api private
6
8
  #
7
9
  class Puppet::SSL::Validator::NoValidator < Puppet::SSL::Validator
@@ -0,0 +1,134 @@
1
+ require 'puppet/ssl'
2
+
3
+ # Verify an SSL connection.
4
+ #
5
+ # @api private
6
+ class Puppet::SSL::Verifier
7
+
8
+ FIVE_MINUTES_AS_SECONDS = 5 * 60
9
+
10
+ attr_reader :ssl_context
11
+
12
+ # Create a verifier using an `ssl_context`.
13
+ #
14
+ # @param hostname [String] FQDN of the server we're attempting to connect to
15
+ # @param ssl_context [Puppet::SSL::SSLContext] ssl_context containing CA certs,
16
+ # CRLs, etc needed to verify the server's certificate chain
17
+ def initialize(hostname, ssl_context)
18
+ @hostname = hostname
19
+ @ssl_context = ssl_context
20
+ end
21
+
22
+ # Return true if `self` is reusable with `verifier` meaning they
23
+ # are using the same `ssl_context`, so there's no loss of security
24
+ # when using a cached connection.
25
+ #
26
+ # @param verifier [Puppet::SSL::Verifier] the verifier to compare against
27
+ # @return [Boolean] return true if a cached connection can be used, false otherwise
28
+ def reusable?(verifier)
29
+ verifier.instance_of?(self.class) &&
30
+ verifier.ssl_context.object_id == @ssl_context.object_id
31
+ end
32
+
33
+ # Configure the `http` connection based on the current `ssl_context`.
34
+ #
35
+ # @param http [Net::HTTP] connection
36
+ # @api private
37
+ def setup_connection(http)
38
+ http.cert_store = @ssl_context[:store]
39
+ http.cert = @ssl_context[:client_cert]
40
+ http.key = @ssl_context[:private_key]
41
+ # default to VERIFY_PEER
42
+ http.verify_mode = if !@ssl_context[:verify_peer]
43
+ OpenSSL::SSL::VERIFY_NONE
44
+ else
45
+ OpenSSL::SSL::VERIFY_PEER
46
+ end
47
+ http.verify_callback = self
48
+ end
49
+
50
+ # This method is called if `Net::HTTP#start` raises an exception, which
51
+ # could be a result of an openssl error during cert verification, due
52
+ # to ruby's `Socket#post_connection_check`, or general SSL connection
53
+ # error.
54
+ #
55
+ # @param http [Net::HTTP] connection
56
+ # @param error [OpenSSL::SSL::SSLError] connection error
57
+ # @raise [Puppet::SSL::CertVerifyError] SSL connection failed due to a
58
+ # verification error with the server's certificate or chain
59
+ # @raise [Puppet::Error] server hostname does not match certificate
60
+ # @raise [OpenSSL::SSL::SSLError] low-level SSL connection failure
61
+ # @api private
62
+ def handle_connection_error(http, error)
63
+ raise @last_error if @last_error
64
+
65
+ # ruby can pass SSL validation but fail post_connection_check
66
+ peer_cert = http.peer_cert
67
+ if peer_cert && !OpenSSL::SSL.verify_certificate_identity(peer_cert, @hostname)
68
+ raise Puppet::SSL::CertMismatchError.new(peer_cert, @hostname)
69
+ else
70
+ raise error
71
+ end
72
+ end
73
+
74
+ # OpenSSL will call this method with the verification result for each cert in
75
+ # the server's chain, working from the root CA to the server's cert. If
76
+ # preverify_ok is `true`, then that cert passed verification. If it's `false`
77
+ # then the current verification error is contained in `store_context.error`.
78
+ # and the current cert is in `store_context.current_cert`.
79
+ #
80
+ # If this method returns `false`, then verification stops and ruby will raise
81
+ # an `OpenSSL::SSL::Error` with "certificate verification failed". If this
82
+ # method returns `true`, then verification continues.
83
+ #
84
+ # If this method ignores a verification error, such as the cert's CRL will be
85
+ # valid within the next 5 minutes, then this method may be called with a
86
+ # different verification error for the same cert.
87
+ #
88
+ # WARNING: If `store_context.error` returns `OpenSSL::X509::V_OK`, don't
89
+ # assume verification passed. Ruby 2.4+ implements certificate hostname
90
+ # checking by default, and if the cert doesn't match the hostname, then the
91
+ # error will be V_OK. Always use `preverify_ok` to determine if verification
92
+ # succeeded or not.
93
+ #
94
+ # @param preverify_ok [Boolean] if `true` the current certificate in `store_context`
95
+ # was verified. Otherwise, check for the current error in `store_context.error`
96
+ # @param store_context [OpenSSL::X509::StoreContext] The context holding the
97
+ # verification result for one certificate
98
+ # @return [Boolean] If `true`, continue verifying the chain, even if that means
99
+ # ignoring the current verification error. If `false`, abort the connection.
100
+ #
101
+ # @api private
102
+ def call(preverify_ok, store_context)
103
+ return true if preverify_ok
104
+
105
+ peer_cert = store_context.current_cert
106
+
107
+ case store_context.error
108
+ when OpenSSL::X509::V_OK
109
+ # chain is from leaf to root, opposite of the order that `call` is invoked
110
+ chain_cert = store_context.chain.first
111
+
112
+ # ruby 2.4 doesn't compare certs based on value, so force to DER byte array
113
+ if peer_cert && chain_cert && peer_cert.to_der == chain_cert.to_der && !OpenSSL::SSL.verify_certificate_identity(peer_cert, @hostname)
114
+ @last_error = Puppet::SSL::CertMismatchError.new(peer_cert, @hostname)
115
+ return false
116
+ end
117
+
118
+ when OpenSSL::X509::V_ERR_CRL_NOT_YET_VALID
119
+ crl = store_context.current_crl
120
+ if crl && crl.last_update && crl.last_update < Time.now + FIVE_MINUTES_AS_SECONDS
121
+ Puppet.debug("Ignoring CRL not yet valid, current time #{Time.now.utc}, CRL last updated #{crl.last_update.utc}")
122
+ return true
123
+ end
124
+ end
125
+
126
+ # TRANSLATORS: `error` is an untranslated message from openssl describing why a certificate in the server's chain is invalid, and `subject` is the identity/name of the failed certificate
127
+ @last_error = Puppet::SSL::CertVerifyError.new(
128
+ _("certificate verify failed [%{error} for %{subject}]") %
129
+ { error: store_context.error_string, subject: peer_cert.subject },
130
+ store_context.error, peer_cert
131
+ )
132
+ false
133
+ end
134
+ end
@@ -0,0 +1,48 @@
1
+ # Allows a `Puppet::SSL::Validator` to be used in situations where a
2
+ # `Verifier` is required, while preserving the legacy validator behavior of:
3
+ #
4
+ # * Loading CA certs from `ssl_client_ca_auth` or `localcacert`
5
+ # * Verifying each cert in the peer's chain is contained in the file
6
+ # loaded above.
7
+ #
8
+ class Puppet::SSL::VerifierAdapter
9
+ attr_reader :validator
10
+
11
+ def initialize(validator)
12
+ @validator = validator
13
+ end
14
+
15
+ # Return true if `self` is reusable with `verifier` meaning they
16
+ # are both using the same class of `Puppet::SSL::Validator`. In this
17
+ # case we only care the Validator class is the same. We can't require
18
+ # the same instances, because a new instance is created each time
19
+ # HttpPool.http_instance is called.
20
+ #
21
+ # @param verifier [Puppet::SSL::Verifier] the verifier to compare against
22
+ # @return [Boolean] return true if a cached connection can be used, false otherwise
23
+ def reusable?(verifier)
24
+ verifier.instance_of?(self.class) &&
25
+ verifier.validator.instance_of?(@validator.class)
26
+ end
27
+
28
+ # Configure the `http` connection based on the current `ssl_context`.
29
+ #
30
+ # @param http [Net::HTTP] connection
31
+ # @api private
32
+ def setup_connection(http)
33
+ @validator.setup_connection(http)
34
+ end
35
+
36
+ # Handle an SSL connection error.
37
+ #
38
+ # @param http [Net::HTTP] connection
39
+ # @param error [OpenSSL::SSL::SSLError] connection error
40
+ # @return (see Puppet::SSL::Verifier#handle_connection_error)
41
+ # @raise [Puppet::SSL::CertVerifyError] SSL connection failed due to a
42
+ # verification error with the server's certificate or chain
43
+ # @raise [Puppet::Error] server hostname does not match certificate
44
+ # @raise [OpenSSL::SSL::SSLError] low-level SSL connection failure
45
+ def handle_connection_error(http, error)
46
+ Puppet::Util::SSL.handle_connection_error(error, @validator, http.address)
47
+ end
48
+ end
@@ -134,8 +134,9 @@ module Puppet::Test
134
134
 
135
135
  Puppet.push_context(
136
136
  {
137
- :trusted_information =>
137
+ trusted_information:
138
138
  Puppet::Context::TrustedInformation.new('local', 'testing', {}),
139
+ ssl_context: Puppet::SSL::SSLContext.new(cacerts: []).freeze
139
140
  },
140
141
  "Context for specs")
141
142
 
@@ -198,7 +198,7 @@ module Puppet
198
198
 
199
199
  newparam(:user) do
200
200
  desc "The user to run the command as.
201
-
201
+
202
202
  > **Note:** Puppet cannot execute commands as other users on Windows.
203
203
 
204
204
  Note that if you use this attribute, any error output is not captured
@@ -407,6 +407,8 @@ module Puppet
407
407
  # If the file exists, return false (i.e., don't run the command),
408
408
  # else return true
409
409
  def check(value)
410
+ #TRANSLATORS 'creates' is a parameter name and should not be translated
411
+ debug(_("Checking that 'creates' path '%{creates_path}' exists") % { creates_path: value })
410
412
  ! Puppet::FileSystem.exist?(value)
411
413
  end
412
414
  end
@@ -581,7 +583,15 @@ module Puppet
581
583
  val = @parameters[check].value
582
584
  val = [val] unless val.is_a? Array
583
585
  val.each do |value|
584
- return false unless @parameters[check].check(value)
586
+ if !@parameters[check].check(value)
587
+ # Give a debug message so users can figure out what command would have been
588
+ # but don't print sensitive commands or parameters in the clear
589
+ cmdstring = @parameters[:command].sensitive ? "[command redacted]" : @parameters[:command].value
590
+
591
+ debug(_("'%{cmd}' won't be executed because of failed check '%{check}'") % { cmd: cmdstring, check: check })
592
+
593
+ return false
594
+ end
585
595
  end
586
596
  end
587
597
  }
@@ -614,11 +624,25 @@ module Puppet
614
624
 
615
625
  private
616
626
  def set_sensitive_parameters(sensitive_parameters)
617
- # Respect sensitive commands
618
- if sensitive_parameters.include?(:command)
619
- sensitive_parameters.delete(:command)
620
- parameter(:command).sensitive = true
627
+ # If any are sensitive, mark all as sensitive
628
+ sensitive = false
629
+ parameters_to_check = [:command, :unless, :onlyif]
630
+
631
+ parameters_to_check.each do |p|
632
+ if sensitive_parameters.include?(p)
633
+ sensitive_parameters.delete(p)
634
+ sensitive = true
635
+ end
621
636
  end
637
+
638
+ if sensitive
639
+ parameters_to_check.each do |p|
640
+ if parameters.include?(p)
641
+ parameter(p).sensitive = true
642
+ end
643
+ end
644
+ end
645
+
622
646
  super(sensitive_parameters)
623
647
  end
624
648
  end
@@ -116,8 +116,13 @@ module Puppet
116
116
  # If we're not following links and we're a link, then we just turn
117
117
  # off mode management entirely.
118
118
  def insync?(currentvalue)
119
+ if provider.respond_to?(:munge_windows_system_group)
120
+ munged_mode = provider.munge_windows_system_group(currentvalue, @should)
121
+ return false if munged_mode.nil?
122
+ currentvalue = munged_mode
123
+ end
119
124
  if stat = @resource.stat and stat.ftype == "link" and @resource[:links] != :follow
120
- self.debug "Not managing symlink mode"
125
+ self.debug _("Not managing symlink mode")
121
126
  return true
122
127
  else
123
128
  return super(currentvalue)
@@ -302,7 +302,8 @@ module Puppet
302
302
  end
303
303
 
304
304
  request.do_request(:fileserver) do |req|
305
- connection = Puppet::Network::HttpPool.http_instance(req.server, req.port)
305
+ ssl_context = Puppet.lookup(:ssl_context)
306
+ connection = Puppet::Network::HttpPool.connection(req.server, req.port, ssl_context: ssl_context)
306
307
  connection.request_get(Puppet::Network::HTTP::API::IndirectedRoutes.request_to_uri(req), add_accept_encoding({"Accept" => BINARY_MIME_TYPES}), &block)
307
308
  end
308
309
  end
@@ -320,7 +321,6 @@ module Puppet
320
321
  end
321
322
  end
322
323
 
323
-
324
324
  def chunk_file_from_source
325
325
  get_from_source do |response|
326
326
  case response.code
@@ -42,19 +42,23 @@ module Puppet
42
42
  end
43
43
 
44
44
  newparam(:server) do
45
- desc "The server providing the remote filebucket service. Defaults to the
46
- value of the `server` setting (that is, the currently configured
47
- puppet master server).
45
+ desc "The server providing the remote filebucket service.
48
46
 
49
- This setting is _only_ consulted if the `path` attribute is set to `false`."
50
- defaultto { Puppet[:server] }
47
+ This setting is _only_ consulted if the `path` attribute is set to `false`.
48
+
49
+ If this attribute is not specified, the first entry in the `server_list`
50
+ configuration setting is used, followed by the value of the `server` setting
51
+ if `server_list` is not set."
51
52
  end
52
53
 
53
54
  newparam(:port) do
54
- desc "The port on which the remote server is listening. Defaults to the
55
- value of the `masterport` setting, which is usually %s." % Puppet[:masterport]
55
+ desc "The port on which the remote server is listening.
56
+
57
+ This setting is _only_ consulted if the `path` attribute is set to `false`.
56
58
 
57
- defaultto { Puppet[:masterport] }
59
+ If this attribute is not specified, the first entry in the `server_list`
60
+ configuration setting is used, followed by the value of the `masterport`
61
+ setting if `server_list` is not set."
58
62
  end
59
63
 
60
64
  newparam(:path) do
@@ -618,7 +618,20 @@ module Puppet
618
618
  end
619
619
 
620
620
  newproperty(:attributes, :parent => Puppet::Property::KeyValue, :required_features => :manages_aix_lam) do
621
- desc "Specify AIX attributes for the user in an array of attribute = value pairs."
621
+ desc "Specify AIX attributes for the user in an array or hash of attribute = value pairs.
622
+
623
+ For example:
624
+
625
+ ```
626
+ ['minage=0', 'maxage=5', 'SYSTEM=compat']
627
+ ```
628
+
629
+ or
630
+
631
+ ```
632
+ attributes => { 'minage' => '0', 'maxage' => '5', 'SYSTEM' => 'compat' }
633
+ ```
634
+ "
622
635
 
623
636
  self.log_only_changed_or_new_keys = true
624
637
 
@@ -1,7 +1,10 @@
1
1
  require 'puppet'
2
+ require 'puppet/util/warnings'
2
3
 
3
4
  module Puppet::Util
4
5
  module Connection
6
+ extend Puppet::Util::Warnings
7
+
5
8
  # The logic for server and port is kind of gross. In summary:
6
9
  # IF an endpoint-specific setting is requested AND that setting has been set by the user
7
10
  # Use that setting.
@@ -26,11 +29,12 @@ module Puppet::Util
26
29
  else
27
30
  server = Puppet.lookup(:server) do
28
31
  if primary_server = Puppet.settings[:server_list][0]
29
- Puppet.debug "Dynamically-bound server lookup failed; using first entry"
32
+ debug_once('Dynamically-bound server lookup failed; using first entry')
30
33
  primary_server[0]
31
34
  else
32
35
  setting ||= :server
33
- Puppet.debug "Dynamically-bound server lookup failed, falling back to #{setting} setting"
36
+ debug_once('Dynamically-bound server lookup failed, falling back to %{setting} setting' %
37
+ {setting: setting})
34
38
  Puppet.settings[setting]
35
39
  end
36
40
  end
@@ -47,7 +51,7 @@ module Puppet::Util
47
51
  # failover-selected port.
48
52
  # @param [Symbol] port_setting The preferred port setting to use
49
53
  # @param [Symbol] server_setting The server setting assoicated with this route.
50
- # @return [String] the port to use for use in the request
54
+ # @return [Integer] the port to use for use in the request
51
55
  def self.determine_port(port_setting, server_setting)
52
56
  if (port_setting && port_setting != :masterport && Puppet.settings.set_by_config?(port_setting)) ||
53
57
  (server_setting && server_setting != :server && Puppet.settings.set_by_config?(server_setting))
@@ -55,7 +59,7 @@ module Puppet::Util
55
59
  else
56
60
  port = Puppet.lookup(:serverport) do
57
61
  if primary_server = Puppet.settings[:server_list][0]
58
- Puppet.debug "Dynamically-bound port lookup failed; using first entry"
62
+ debug_once('Dynamically-bound port lookup failed; using first entry')
59
63
 
60
64
  # Port might not be set, so we want to fallback in that
61
65
  # case. We know we don't need to use `setting` here, since
@@ -63,7 +67,8 @@ module Puppet::Util
63
67
  (primary_server[1] || Puppet.settings[:masterport])
64
68
  else
65
69
  port_setting ||= :masterport
66
- Puppet.debug "Dynamically-bound port lookup failed; falling back to #{port_setting} setting"
70
+ debug_once('Dynamically-bound port lookup failed; falling back to %{port_setting} setting' %
71
+ {port_setting: port_setting})
67
72
  Puppet.settings[port_setting]
68
73
  end
69
74
  end
@@ -1,6 +1,9 @@
1
1
  require 'puppet'
2
+ require 'puppet/util/warnings'
2
3
 
3
4
  class Puppet::Util::Feature
5
+ include Puppet::Util::Warnings
6
+
4
7
  attr_reader :path
5
8
 
6
9
  # Create a new feature test. You have to pass the feature name, and it must be
@@ -109,8 +112,14 @@ class Puppet::Util::Feature
109
112
  begin
110
113
  require lib
111
114
  true
112
- rescue ScriptError => detail
113
- Puppet.debug _("Failed to load library '%{lib}' for feature '%{name}': %{detail}") % { lib: lib, name: name, detail: detail }
115
+ rescue LoadError
116
+ # Expected case. Required library insn't installed.
117
+ debug_once(_("Could not find library '%{lib}' required to enable feature '%{name}'") %
118
+ {lib: lib, name: name})
119
+ false
120
+ rescue StandardError, ScriptError => detail
121
+ debug_once(_("Exception occurred while loading library '%{lib}' required to enable feature '%{name}': %{detail}") %
122
+ {lib: lib, name: name, detail: detail})
114
123
  false
115
124
  end
116
125
  end