puppet 6.22.1 → 6.23.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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +14 -14
  3. data/ext/osx/puppet.plist +2 -0
  4. data/lib/puppet/application/agent.rb +12 -5
  5. data/lib/puppet/application/apply.rb +2 -1
  6. data/lib/puppet/application/device.rb +2 -1
  7. data/lib/puppet/application/resource.rb +2 -1
  8. data/lib/puppet/application/script.rb +2 -1
  9. data/lib/puppet/configurer/downloader.rb +2 -1
  10. data/lib/puppet/defaults.rb +5 -3
  11. data/lib/puppet/file_serving/fileset.rb +14 -2
  12. data/lib/puppet/functions/all.rb +1 -1
  13. data/lib/puppet/functions/camelcase.rb +1 -1
  14. data/lib/puppet/functions/capitalize.rb +2 -2
  15. data/lib/puppet/functions/downcase.rb +2 -2
  16. data/lib/puppet/functions/get.rb +5 -5
  17. data/lib/puppet/functions/group_by.rb +13 -5
  18. data/lib/puppet/functions/lest.rb +1 -1
  19. data/lib/puppet/functions/new.rb +100 -100
  20. data/lib/puppet/functions/partition.rb +4 -4
  21. data/lib/puppet/functions/require.rb +5 -5
  22. data/lib/puppet/functions/sort.rb +3 -3
  23. data/lib/puppet/functions/tree_each.rb +7 -9
  24. data/lib/puppet/functions/type.rb +4 -4
  25. data/lib/puppet/functions/upcase.rb +2 -2
  26. data/lib/puppet/http/resolver/server_list.rb +15 -4
  27. data/lib/puppet/http/service/compiler.rb +69 -0
  28. data/lib/puppet/http/service/file_server.rb +2 -1
  29. data/lib/puppet/indirector/catalog/compiler.rb +1 -0
  30. data/lib/puppet/indirector/file_metadata/rest.rb +1 -0
  31. data/lib/puppet/parser/functions/fqdn_rand.rb +14 -6
  32. data/lib/puppet/pops/types/p_sem_ver_type.rb +8 -2
  33. data/lib/puppet/pops/types/p_sensitive_type.rb +10 -0
  34. data/lib/puppet/provider/package/nim.rb +11 -6
  35. data/lib/puppet/provider/service/systemd.rb +13 -3
  36. data/lib/puppet/provider/service/windows.rb +38 -0
  37. data/lib/puppet/provider/user/directoryservice.rb +25 -12
  38. data/lib/puppet/reference/configuration.rb +1 -1
  39. data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
  40. data/lib/puppet/type/file.rb +19 -1
  41. data/lib/puppet/type/file/selcontext.rb +1 -1
  42. data/lib/puppet/type/service.rb +18 -38
  43. data/lib/puppet/type/tidy.rb +21 -2
  44. data/lib/puppet/type/user.rb +38 -20
  45. data/lib/puppet/util/selinux.rb +30 -4
  46. data/lib/puppet/version.rb +1 -1
  47. data/locales/puppet.pot +109 -101
  48. data/man/man5/puppet.conf.5 +272 -252
  49. data/man/man8/puppet-agent.8 +1 -1
  50. data/man/man8/puppet-apply.8 +1 -1
  51. data/man/man8/puppet-catalog.8 +1 -1
  52. data/man/man8/puppet-config.8 +1 -1
  53. data/man/man8/puppet-describe.8 +1 -1
  54. data/man/man8/puppet-device.8 +1 -1
  55. data/man/man8/puppet-doc.8 +1 -1
  56. data/man/man8/puppet-epp.8 +1 -1
  57. data/man/man8/puppet-facts.8 +1 -1
  58. data/man/man8/puppet-filebucket.8 +1 -1
  59. data/man/man8/puppet-generate.8 +1 -1
  60. data/man/man8/puppet-help.8 +1 -1
  61. data/man/man8/puppet-key.8 +1 -1
  62. data/man/man8/puppet-lookup.8 +1 -1
  63. data/man/man8/puppet-man.8 +1 -1
  64. data/man/man8/puppet-module.8 +1 -1
  65. data/man/man8/puppet-node.8 +1 -1
  66. data/man/man8/puppet-parser.8 +1 -1
  67. data/man/man8/puppet-plugin.8 +1 -1
  68. data/man/man8/puppet-report.8 +1 -1
  69. data/man/man8/puppet-resource.8 +1 -1
  70. data/man/man8/puppet-script.8 +1 -1
  71. data/man/man8/puppet-ssl.8 +1 -1
  72. data/man/man8/puppet-status.8 +1 -1
  73. data/man/man8/puppet.8 +2 -2
  74. data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -57
  75. data/spec/fixtures/ssl/127.0.0.1.pem +52 -31
  76. data/spec/fixtures/ssl/bad-basic-constraints.pem +57 -35
  77. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +57 -35
  78. data/spec/fixtures/ssl/ca.pem +57 -35
  79. data/spec/fixtures/ssl/crl.pem +28 -18
  80. data/spec/fixtures/ssl/ec-key.pem +11 -11
  81. data/spec/fixtures/ssl/ec.pem +33 -24
  82. data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
  83. data/spec/fixtures/ssl/encrypted-key.pem +108 -58
  84. data/spec/fixtures/ssl/intermediate-agent-crl.pem +28 -19
  85. data/spec/fixtures/ssl/intermediate-agent.pem +57 -36
  86. data/spec/fixtures/ssl/intermediate-crl.pem +31 -21
  87. data/spec/fixtures/ssl/intermediate.pem +57 -36
  88. data/spec/fixtures/ssl/pluto-key.pem +107 -57
  89. data/spec/fixtures/ssl/pluto.pem +52 -30
  90. data/spec/fixtures/ssl/request-key.pem +107 -57
  91. data/spec/fixtures/ssl/request.pem +47 -26
  92. data/spec/fixtures/ssl/revoked-key.pem +107 -57
  93. data/spec/fixtures/ssl/revoked.pem +52 -30
  94. data/spec/fixtures/ssl/signed-key.pem +107 -57
  95. data/spec/fixtures/ssl/signed.pem +52 -30
  96. data/spec/fixtures/ssl/tampered-cert.pem +52 -30
  97. data/spec/fixtures/ssl/tampered-csr.pem +47 -26
  98. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -57
  99. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -29
  100. data/spec/fixtures/ssl/unknown-ca-key.pem +107 -57
  101. data/spec/fixtures/ssl/unknown-ca.pem +55 -33
  102. data/spec/integration/application/resource_spec.rb +30 -0
  103. data/spec/lib/puppet/test_ca.rb +2 -2
  104. data/spec/unit/application/agent_spec.rb +7 -2
  105. data/spec/unit/configurer/downloader_spec.rb +6 -0
  106. data/spec/unit/configurer_spec.rb +23 -0
  107. data/spec/unit/file_serving/fileset_spec.rb +60 -0
  108. data/spec/unit/gettext/config_spec.rb +12 -0
  109. data/spec/unit/http/service/compiler_spec.rb +123 -0
  110. data/spec/unit/indirector/catalog/compiler_spec.rb +14 -10
  111. data/spec/unit/parser/functions/fqdn_rand_spec.rb +15 -1
  112. data/spec/unit/pops/types/p_sem_ver_type_spec.rb +18 -0
  113. data/spec/unit/pops/types/p_sensitive_type_spec.rb +18 -0
  114. data/spec/unit/provider/package/nim_spec.rb +42 -0
  115. data/spec/unit/provider/service/init_spec.rb +1 -0
  116. data/spec/unit/provider/service/openwrt_spec.rb +3 -1
  117. data/spec/unit/provider/service/systemd_spec.rb +42 -8
  118. data/spec/unit/provider/service/windows_spec.rb +202 -0
  119. data/spec/unit/provider/user/directoryservice_spec.rb +67 -35
  120. data/spec/unit/ssl/state_machine_spec.rb +19 -5
  121. data/spec/unit/transaction/additional_resource_generator_spec.rb +0 -2
  122. data/spec/unit/transaction_spec.rb +18 -20
  123. data/spec/unit/type/file/selinux_spec.rb +3 -3
  124. data/spec/unit/type/service_spec.rb +59 -188
  125. data/spec/unit/type/tidy_spec.rb +17 -7
  126. data/spec/unit/type/user_spec.rb +45 -0
  127. data/spec/unit/util/selinux_spec.rb +87 -16
  128. data/tasks/generate_cert_fixtures.rake +2 -2
  129. metadata +4 -2
@@ -4,19 +4,19 @@
4
4
  # the second containing the rest.
5
5
  Puppet::Functions.create_function(:partition) do
6
6
  # @param collection A collection of things to partition.
7
- # @example Partition array of empty strings, results in e.g. [[''], [b, c]]
7
+ # @example Partition array of empty strings, results in e.g. `[[''], [b, c]]`
8
8
  # ```puppet
9
9
  # ['', b, c].partition |$s| { $s.empty }
10
10
  # ```
11
- # @example Partition array of strings using index, results in e.g. [['', 'ab'], ['b']]
11
+ # @example Partition array of strings using index, results in e.g. `[['', 'ab'], ['b']]`
12
12
  # ```puppet
13
13
  # ['', b, ab].partition |$i, $s| { $i == 2 or $s.empty }
14
14
  # ```
15
- # @example Partition hash of strings by key-value pair, results in e.g. [[['b', []]], [['a', [1, 2]]]]
15
+ # @example Partition hash of strings by key-value pair, results in e.g. `[[['b', []]], [['a', [1, 2]]]]`
16
16
  # ```puppet
17
17
  # { a => [1, 2], b => [] }.partition |$kv| { $kv[1].empty }
18
18
  # ```
19
- # @example Partition hash of strings by key and value, results in e.g. [[['b', []]], [['a', [1, 2]]]]
19
+ # @example Partition hash of strings by key and value, results in e.g. `[[['b', []]], [['a', [1, 2]]]]`
20
20
  # ```puppet
21
21
  # { a => [1, 2], b => [] }.partition |$k, $v| { $v.empty }
22
22
  # ```
@@ -4,13 +4,13 @@
4
4
  # The relationship metaparameters work well for specifying relationships
5
5
  # between individual resources, but they can be clumsy for specifying
6
6
  # relationships between classes. This function is a superset of the
7
- # 'include' function, adding a class relationship so that the requiring
7
+ # `include` function, adding a class relationship so that the requiring
8
8
  # class depends on the required class.
9
9
  #
10
- # Warning: using require in place of include can lead to unwanted dependency cycles.
10
+ # Warning: using `require` in place of `include` can lead to unwanted dependency cycles.
11
11
  #
12
- # For instance the following manifest, with 'require' instead of 'include' would produce a nasty
13
- # dependence cycle, because notify imposes a before between File[/foo] and Service[foo]:
12
+ # For instance, the following manifest, with `require` instead of `include`, would produce a nasty
13
+ # dependence cycle, because `notify` imposes a `before` between `File[/foo]` and `Service[foo]`:
14
14
  #
15
15
  # ```puppet
16
16
  # class myservice {
@@ -32,7 +32,7 @@
32
32
  # resource and relationship expressions.
33
33
  #
34
34
  # - Since 4.0.0 Class and Resource types, absolute names
35
- # - Since 4.7.0 Returns an Array[Type[Class]] with references to the required classes
35
+ # - Since 4.7.0 Returns an `Array[Type[Class]]` with references to the required classes
36
36
  #
37
37
  Puppet::Functions.create_function(:require, Puppet::Functions::InternalFunction) do
38
38
  dispatch :require_impl do
@@ -2,9 +2,9 @@
2
2
  # Please note: This function is based on Ruby String comparison and as such may not be entirely UTF8 compatible.
3
3
  # To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
4
4
  #
5
- # This function is compatible with the function sort() in stdlib.
5
+ # This function is compatible with the function `sort()` in `stdlib`.
6
6
  # * Comparison of characters in a string always uses a system locale and may not be what is expected for a particular locale
7
- # * Sorting is based on Ruby's <=> operator unless a lambda is given that performs the comparison.
7
+ # * Sorting is based on Ruby's `<=>` operator unless a lambda is given that performs the comparison.
8
8
  # * comparison of strings is case dependent (use lambda with `compare($a,$b)` to ignore case)
9
9
  # * comparison of mixed data types raises an error (if there is the need to sort mixed data types use a lambda)
10
10
  #
@@ -49,7 +49,7 @@
49
49
  # }
50
50
  # })
51
51
  # ```
52
- # Would notice [2,3,'a','b']
52
+ # Would notice `[2,3,'a','b']`
53
53
  #
54
54
  # @since 6.0.0 - supporting a lambda to do compare
55
55
  #
@@ -6,13 +6,13 @@
6
6
  #
7
7
  # 1. An `Array`, `Hash`, `Iterator`, or `Object` that the function will iterate over.
8
8
  # 2. An optional hash with the options:
9
- # * `include_containers` => `Optional[Boolean]` # default true - if containers should be given to the lambda
10
- # * `include_values` => `Optional[Boolean]` # default true - if non containers should be given to the lambda
11
- # * `include_root` => `Optional[Boolean]` # default true - if the root container should be given to the lambda
9
+ # * `include_containers` => `Optional[Boolean]` # default `true` - if containers should be given to the lambda
10
+ # * `include_values` => `Optional[Boolean]` # default `true` - if non containers should be given to the lambda
11
+ # * `include_root` => `Optional[Boolean]` # default `true` - if the root container should be given to the lambda
12
12
  # * `container_type` => `Optional[Type[Variant[Array, Hash, Object]]]` # a type that determines what a container is - can only
13
13
  # be set to a type that matches the default `Variant[Array, Hash, Object]`.
14
14
  # * `order` => `Enum[depth_first, breadth_first]` # default ´depth_first`, the order in which elements are visited
15
- # * `include_refs` => Optional[Boolean] # default `false`, if attributes in objects marked as bing of `reference` kind
15
+ # * `include_refs` => `Optional[Boolean]` # default `false`, if attributes in objects marked as bing of `reference` kind
16
16
  # should be included.
17
17
  # 3. An optional lambda, which the function calls for each element in the first argument. It must
18
18
  # accept one or two arguments; either `$path`, and `$value`, or just `$value`.
@@ -46,14 +46,12 @@
46
46
  # [1, [2, 3], 4]
47
47
  # ```
48
48
  #
49
- # Results in:
50
- #
51
- # If containers are skipped:
49
+ # If containers are skipped, results in:
52
50
  #
53
51
  # * `depth_first` order `1`, `2`, `3`, `4`
54
52
  # * `breadth_first` order `1`, `4`,`2`, `3`
55
53
  #
56
- # If containers and root, are included:
54
+ # If containers and root are included, results in:
57
55
  #
58
56
  # * `depth_first` order `[1, [2, 3], 4]`, `1`, `[2, 3]`, `2`, `3`, `4`
59
57
  # * `breadth_first` order `[1, [2, 3], 4]`, `1`, `[2, 3]`, `4`, `2`, `3`
@@ -96,7 +94,7 @@
96
94
  #
97
95
  # Any Puppet Type system data type can be used to filter what is
98
96
  # considered to be a container, but it must be a narrower type than one of
99
- # the default Array, Hash, Object types - for example it is not possible to make a
97
+ # the default `Array`, `Hash`, `Object` types - for example it is not possible to make a
100
98
  # `String` be a container type.
101
99
  #
102
100
  # @example Only `Array` as container type
@@ -35,10 +35,10 @@
35
35
  #
36
36
  # Would notice the four values:
37
37
  #
38
- # 1. 'Array[Numeric]'
39
- # 2. 'Array[Numeric, 2, 2]'
40
- # 3. 'Tuple[Float[3.14], Integer[42,42]]]'
41
- # 4. 'Tuple[Float[3.14], Integer[42,42]]]'
38
+ # 1. `Array[Numeric]`
39
+ # 2. `Array[Numeric, 2, 2]`
40
+ # 3. `Tuple[Float[3.14], Integer[42,42]]]`
41
+ # 4. `Tuple[Float[3.14], Integer[42,42]]]`
42
42
  #
43
43
  # @since 4.4.0
44
44
  #
@@ -22,14 +22,14 @@
22
22
  # 'hello'.upcase()
23
23
  # upcase('hello')
24
24
  # ```
25
- # Would both result in "HELLO"
25
+ # Would both result in `"HELLO"`
26
26
  #
27
27
  # @example Converting an Array to upper case
28
28
  # ```puppet
29
29
  # ['a', 'b'].upcase()
30
30
  # upcase(['a', 'b'])
31
31
  # ```
32
- # Would both result in ['A', 'B']
32
+ # Would both result in `['A', 'B']`
33
33
  #
34
34
  # @example Converting a Hash to upper case
35
35
  # ```puppet
@@ -54,7 +54,7 @@ class Puppet::HTTP::Resolver::ServerList < Puppet::HTTP::Resolver
54
54
  end
55
55
 
56
56
  # Return the first simple service status endpoint we can connect to
57
- @server_list_setting.value.each do |server|
57
+ @server_list_setting.value.each_with_index do |server, index|
58
58
  host = server[0]
59
59
  port = server[1] || @default_port
60
60
 
@@ -64,10 +64,21 @@ class Puppet::HTTP::Resolver::ServerList < Puppet::HTTP::Resolver
64
64
  @resolved_url = service.url
65
65
  return Puppet::HTTP::Service.create_service(@client, session, name, @resolved_url.host, @resolved_url.port)
66
66
  rescue Puppet::HTTP::ResponseError => detail
67
- Puppet.log_exception(detail, _("Puppet server %{host}:%{port} is unavailable: %{code} %{reason}") %
68
- { host: service.url.host, port: service.url.port, code: detail.response.code, reason: detail.response.reason })
67
+ if index < @server_list_setting.value.length - 1
68
+ Puppet.warning(_("Puppet server %{host}:%{port} is unavailable: %{code} %{reason}") %
69
+ { host: service.url.host, port: service.url.port, code: detail.response.code, reason: detail.response.reason } +
70
+ ' ' + _("Trying with next server from server_list."))
71
+ else
72
+ Puppet.log_exception(detail, _("Puppet server %{host}:%{port} is unavailable: %{code} %{reason}") %
73
+ { host: service.url.host, port: service.url.port, code: detail.response.code, reason: detail.response.reason })
74
+ end
69
75
  rescue Puppet::HTTP::HTTPError => detail
70
- Puppet.log_exception(detail, _("Unable to connect to server from server_list setting: %{detail}") % {detail: detail})
76
+ if index < @server_list_setting.value.length - 1
77
+ Puppet.warning(_("Unable to connect to server from server_list setting: %{detail}") % {detail: detail} +
78
+ ' ' + _("Trying with next server from server_list."))
79
+ else
80
+ Puppet.log_exception(detail, _("Unable to connect to server from server_list setting: %{detail}") % {detail: detail})
81
+ end
71
82
  end
72
83
  end
73
84
 
@@ -129,6 +129,75 @@ class Puppet::HTTP::Service::Compiler < Puppet::HTTP::Service
129
129
  [response, deserialize(response, Puppet::Resource::Catalog)]
130
130
  end
131
131
 
132
+ #
133
+ # @api private
134
+ #
135
+ # Submit a POST request to request a catalog to the server using v4 endpoint
136
+ #
137
+ # @param [String] certname The name of the node for which to compile the catalog.
138
+ # @param [Hash] persistent A hash containing two required keys, facts and catalog,
139
+ # which when set to true will cause the facts and reports to be stored in
140
+ # PuppetDB, or discarded if set to false.
141
+ # @param [String] environment The name of the environment for which to compile the catalog.
142
+ # @param [Hash] facts A hash with a required values key, containing a hash of all the
143
+ # facts for the node. If not provided, Puppet will attempt to fetch facts for the node
144
+ # from PuppetDB.
145
+ # @param [Hash] trusted_facts A hash with a required values key containing a hash of
146
+ # the trusted facts for a node
147
+ # @param [String] transaction_uuid The id for tracking the catalog compilation and
148
+ # report submission.
149
+ # @param [String] job_id The id of the orchestrator job that triggered this run.
150
+ # @param [Hash] options A hash of options beyond direct input to catalogs. Options:
151
+ # - prefer_requested_environment Whether to always override a node's classified
152
+ # environment with the one supplied in the request. If this is true and no environment
153
+ # is supplied, fall back to the classified environment, or finally, 'production'.
154
+ # - capture_logs Whether to return the errors and warnings that occurred during
155
+ # compilation alongside the catalog in the response body.
156
+ # - log_level The logging level to use during the compile when capture_logs is true.
157
+ # Options are 'err', 'warning', 'info', and 'debug'.
158
+ #
159
+ # @return [Array<Puppet::HTTP::Response, Puppet::Resource::Catalog, Array<String>>] An array
160
+ # containing the request response, the deserialized catalog returned by
161
+ # the server and array containing logs (log array will be empty if capture_logs is false)
162
+ #
163
+ def post_catalog4(certname, persistence:, environment:, facts: nil, trusted_facts: nil, transaction_uuid: nil, job_id: nil, options: nil)
164
+ unless persistence.is_a?(Hash) && (missing = [:facts, :catalog] - persistence.keys.map(&:to_sym)).empty?
165
+ raise ArgumentError.new("The 'persistence' hash is missing the keys: #{missing.join(', ')}")
166
+ end
167
+ raise ArgumentError.new("Facts must be a Hash not a #{facts.class}") unless facts.nil? || facts.is_a?(Hash)
168
+ body = {
169
+ certname: certname,
170
+ persistence: persistence,
171
+ environment: environment,
172
+ transaction_uuid: transaction_uuid,
173
+ job_id: job_id,
174
+ options: options
175
+ }
176
+ body[:facts] = { values: facts } unless facts.nil?
177
+ body[:trusted_facts] = { values: trusted_facts } unless trusted_facts.nil?
178
+ headers = add_puppet_headers(
179
+ 'Accept' => get_mime_types(Puppet::Resource::Catalog).join(', '),
180
+ 'Content-Type' => 'application/json'
181
+ )
182
+
183
+ url = URI::HTTPS.build(host: @url.host, port: @url.port, path: Puppet::Util.uri_encode("/puppet/v4/catalog"))
184
+ response = @client.post(
185
+ url,
186
+ body.to_json,
187
+ headers: headers
188
+ )
189
+ process_response(response)
190
+ begin
191
+ response_body = JSON.parse(response.body)
192
+ catalog = Puppet::Resource::Catalog.from_data_hash(response_body['catalog'])
193
+ rescue => err
194
+ raise Puppet::HTTP::SerializationError.new("Failed to deserialize catalog from puppetserver response: #{err.message}", err)
195
+ end
196
+
197
+ logs = response_body['logs'] || []
198
+ [response, catalog, logs]
199
+ end
200
+
132
201
  #
133
202
  # @api private
134
203
  #
@@ -106,7 +106,7 @@ class Puppet::HTTP::Service::FileServer < Puppet::HTTP::Service
106
106
  # An array with the request response and an array of the deserialized
107
107
  # metadata for each file returned from the server
108
108
  #
109
- def get_file_metadatas(path: nil, environment:, recurse: :false, recurselimit: nil, ignore: nil, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore)
109
+ def get_file_metadatas(path: nil, environment:, recurse: :false, recurselimit: nil, max_files: nil, ignore: nil, links: :manage, checksum_type: Puppet[:digest_algorithm], source_permissions: :ignore)
110
110
  validate_path(path)
111
111
 
112
112
  headers = add_puppet_headers('Accept' => get_mime_types(Puppet::FileServing::Metadata).join(', '))
@@ -117,6 +117,7 @@ class Puppet::HTTP::Service::FileServer < Puppet::HTTP::Service
117
117
  params: {
118
118
  recurse: recurse,
119
119
  recurselimit: recurselimit,
120
+ max_files: max_files,
120
121
  ignore: ignore,
121
122
  links: links,
122
123
  checksum_type: checksum_type,
@@ -194,6 +194,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
194
194
  :source_permissions => resource[:source_permissions] ? resource[:source_permissions].to_sym : :ignore,
195
195
  :recurse => true,
196
196
  :recurselimit => resource[:recurselimit],
197
+ :max_files => resource[:max_files],
197
198
  :ignore => resource[:ignore],
198
199
  }
199
200
 
@@ -46,6 +46,7 @@ class Puppet::Indirector::FileMetadata::Rest < Puppet::Indirector::REST
46
46
  environment: request.environment.to_s,
47
47
  recurse: request.options[:recurse],
48
48
  recurselimit: request.options[:recurselimit],
49
+ max_files: request.options[:max_files],
49
50
  ignore: request.options[:ignore],
50
51
  links: request.options[:links],
51
52
  checksum_type: request.options[:checksum_type],
@@ -2,13 +2,16 @@ require 'digest/md5'
2
2
  require 'digest/sha2'
3
3
 
4
4
  Puppet::Parser::Functions::newfunction(:fqdn_rand, :arity => -2, :type => :rvalue, :doc =>
5
- "Usage: `fqdn_rand(MAX, [SEED])`. MAX is required and must be a positive
6
- integer; SEED is optional and may be any number or string.
5
+ "Usage: `fqdn_rand(MAX, [SEED], [DOWNCASE])`. MAX is required and must be a positive
6
+ integer; SEED is optional and may be any number or string; DOWNCASE is optional
7
+ and should be a boolean true or false.
7
8
 
8
9
  Generates a random Integer number greater than or equal to 0 and less than MAX,
9
10
  combining the `$fqdn` fact and the value of SEED for repeatable randomness.
10
11
  (That is, each node will get a different random number from this function, but
11
- a given node's result will be the same every time unless its hostname changes.)
12
+ a given node's result will be the same every time unless its hostname changes.) If
13
+ DOWNCASE is true, then the `fqdn` fact will be downcased when computing the value
14
+ so that the result is not sensitive to the case of the `fqdn` fact.
12
15
 
13
16
  This function is usually used for spacing out runs of resource-intensive cron
14
17
  tasks that run on many nodes, which could cause a thundering herd or degrade
@@ -17,7 +20,12 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :arity => -2, :type => :rvalu
17
20
  node. (For example, `fqdn_rand(30)`, `fqdn_rand(30, 'expensive job 1')`, and
18
21
  `fqdn_rand(30, 'expensive job 2')` will produce totally different numbers.)") do |args|
19
22
  max = args.shift.to_i
20
-
23
+ initial_seed = args.shift
24
+ downcase = !!args.shift
25
+
26
+ fqdn = self['::fqdn']
27
+ fqdn = fqdn.downcase if downcase
28
+
21
29
  # Puppet 5.4's fqdn_rand function produces a different value than earlier versions
22
30
  # for the same set of inputs.
23
31
  # This causes problems because the values are often written into service configuration files.
@@ -27,9 +35,9 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :arity => -2, :type => :rvalu
27
35
  # when running on a non-FIPS enabled platform and only using SHA256 on FIPS enabled
28
36
  # platforms.
29
37
  if Puppet::Util::Platform.fips_enabled?
30
- seed = Digest::SHA256.hexdigest([self['::fqdn'],max,args].join(':')).hex
38
+ seed = Digest::SHA256.hexdigest([fqdn,max,initial_seed].join(':')).hex
31
39
  else
32
- seed = Digest::MD5.hexdigest([self['::fqdn'],max,args].join(':')).hex
40
+ seed = Digest::MD5.hexdigest([fqdn,max,initial_seed].join(':')).hex
33
41
  end
34
42
 
35
43
  Puppet::Util.deterministic_rand_int(seed,max)
@@ -95,16 +95,22 @@ class PSemVerType < PScalarType
95
95
  end
96
96
 
97
97
  def from_args(major, minor, patch, prerelease = nil, build = nil)
98
- SemanticPuppet::Version.new(major, minor, patch, prerelease, build)
98
+ SemanticPuppet::Version.new(major, minor, patch, to_array(prerelease), to_array(build))
99
99
  end
100
100
 
101
101
  def from_hash(hash)
102
- SemanticPuppet::Version.new(hash['major'], hash['minor'], hash['patch'], hash['prerelease'], hash['build'])
102
+ SemanticPuppet::Version.new(hash['major'], hash['minor'], hash['patch'], to_array(hash['prerelease']), to_array(hash['build']))
103
103
  end
104
104
 
105
105
  def on_error(str)
106
106
  _("The string '%{str}' cannot be converted to a SemVer") % { str: str }
107
107
  end
108
+
109
+ private
110
+
111
+ def to_array(component)
112
+ component ? [component] : nil
113
+ end
108
114
  end
109
115
  end
110
116
 
@@ -24,6 +24,16 @@ class PSensitiveType < PTypeWithContainedType
24
24
  def inspect
25
25
  "#<#{self}>"
26
26
  end
27
+
28
+ def hash
29
+ @value.hash
30
+ end
31
+
32
+ def ==(other)
33
+ other.is_a?(Sensitive) &&
34
+ other.hash == hash
35
+ end
36
+ alias eql? ==
27
37
  end
28
38
 
29
39
  def self.register_ptype(loader, ir)
@@ -154,20 +154,25 @@ Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do
154
154
  # I spent a lot of time trying to figure out a solution that didn't
155
155
  # require parsing the `nimclient -o showres` output and was unable to
156
156
  # do so.
157
- self::HEADER_LINE_REGEX = /^([^\s]+)\s+[^@]+@@(I|R):(\1)\s+[^\s]+$/
158
- self::PACKAGE_LINE_REGEX = /^.*@@(I|R):(.*)$/
159
- self::RPM_PACKAGE_REGEX = /^(.*)-(.*-\d+) \2$/
157
+ self::HEADER_LINE_REGEX = /^([^\s]+)\s+[^@]+@@(I|R|S):(\1)\s+[^\s]+$/
158
+ self::PACKAGE_LINE_REGEX = /^.*@@(I|R|S):(.*)$/
159
+ self::RPM_PACKAGE_REGEX = /^(.*)-(.*-\d+\w*) \2$/
160
160
  self::INSTALLP_PACKAGE_REGEX = /^(.*) (.*)$/
161
161
 
162
162
  # Here is some sample output that shows what the above regexes will be up
163
163
  # against:
164
- # FOR AN INSTALLP PACKAGE:
164
+ # FOR AN INSTALLP(bff) PACKAGE:
165
165
  #
166
166
  # mypackage.foo ALL @@I:mypackage.foo _all_filesets
167
- # @ 1.2.3.1 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.1
168
167
  # + 1.2.3.4 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.4
169
168
  # + 1.2.3.8 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.8
170
169
  #
170
+ # FOR AN INSTALLP(bff) PACKAGE with security update:
171
+ #
172
+ # bos.net ALL @@S:bos.net _all_filesets
173
+ # + 7.2.0.1 TCP/IP ntp Applications @@S:bos.net.tcp.ntp 7.2.0.1
174
+ # + 7.2.0.2 TCP/IP ntp Applications @@S:bos.net.tcp.ntp 7.2.0.2
175
+ #
171
176
  # FOR AN RPM PACKAGE:
172
177
  #
173
178
  # mypackage.foo ALL @@R:mypackage.foo _all_filesets
@@ -243,7 +248,7 @@ Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do
243
248
  package_string = match.captures[1]
244
249
 
245
250
  case package_type_flag
246
- when "I"
251
+ when "I","S"
247
252
  parse_installp_package_string(package_string)
248
253
  when "R"
249
254
  parse_rpm_package_string(package_string)
@@ -45,8 +45,13 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
45
45
  def enabled_insync?(current)
46
46
  case cached_enabled?[:output]
47
47
  when 'static'
48
- Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
49
- return true
48
+ # masking static services is OK, but enabling/disabling them is not
49
+ if @resource[:enable] == :mask
50
+ current == @resource[:enable]
51
+ else
52
+ Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
53
+ return true
54
+ end
50
55
  when 'indirect'
51
56
  Puppet.debug("Service #{@resource[:name]} is in 'indirect' state and cannot be enabled/disabled")
52
57
  return true
@@ -159,10 +164,15 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
159
164
  end
160
165
 
161
166
  def mask
162
- self.disable
167
+ disable if exist?
163
168
  systemctl_change_enable(:mask)
164
169
  end
165
170
 
171
+ def exist?
172
+ result = execute([command(:systemctl), 'cat', '--', @resource[:name]], :failonfail => false)
173
+ result.exitstatus == 0
174
+ end
175
+
166
176
  def unmask
167
177
  systemctl_change_enable(:unmask)
168
178
  end