chef-dk 2.3.4 → 2.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +22 -18
  3. data/Gemfile.lock +184 -254
  4. data/README.md +1 -1
  5. data/Rakefile +1 -1
  6. data/acceptance/Gemfile.lock +27 -32
  7. data/lib/chef-dk/chef_server_api_multi.rb +73 -0
  8. data/lib/chef-dk/command/update.rb +5 -12
  9. data/lib/chef-dk/configurable.rb +19 -0
  10. data/lib/chef-dk/cookbook_omnifetch.rb +1 -0
  11. data/lib/chef-dk/exceptions.rb +11 -0
  12. data/lib/chef-dk/generator.rb +1 -1
  13. data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -0
  14. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +5 -4
  15. data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +164 -0
  16. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +3 -3
  17. data/lib/chef-dk/policyfile/dsl.rb +16 -0
  18. data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -0
  19. data/lib/chef-dk/policyfile/local_lock_fetcher.rb +122 -0
  20. data/lib/chef-dk/policyfile/lock_applier.rb +80 -0
  21. data/lib/chef-dk/policyfile/null_cookbook_source.rb +4 -0
  22. data/lib/chef-dk/policyfile/policyfile_location_specification.rb +122 -0
  23. data/lib/chef-dk/policyfile_compiler.rb +129 -16
  24. data/lib/chef-dk/policyfile_lock.rb +30 -0
  25. data/lib/chef-dk/policyfile_services/install.rb +7 -1
  26. data/lib/chef-dk/policyfile_services/update_attributes.rb +10 -2
  27. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +14 -1
  28. data/lib/chef-dk/version.rb +1 -1
  29. data/omnibus_overrides.rb +6 -6
  30. data/spec/unit/chef_server_api_multi_spec.rb +120 -0
  31. data/spec/unit/command/update_spec.rb +3 -3
  32. data/spec/unit/configurable_spec.rb +27 -0
  33. data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -0
  34. data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -0
  35. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +48 -0
  36. data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -0
  37. data/spec/unit/policyfile/local_lock_fetcher_spec.rb +161 -0
  38. data/spec/unit/policyfile/lock_applier_spec.rb +100 -0
  39. data/spec/unit/policyfile_demands_spec.rb +1 -1
  40. data/spec/unit/policyfile_includes_dsl_spec.rb +159 -0
  41. data/spec/unit/policyfile_includes_spec.rb +720 -0
  42. data/spec/unit/policyfile_install_with_includes_spec.rb +232 -0
  43. data/spec/unit/policyfile_lock_build_spec.rb +11 -2
  44. data/spec/unit/policyfile_services/update_attributes_spec.rb +13 -0
  45. metadata +28 -3
data/README.md CHANGED
@@ -314,7 +314,7 @@ For information on contributing to this project see <https://github.com/chef/che
314
314
 
315
315
  # For ChefDK Developers
316
316
 
317
- See the [Development Guide](DEVELOPMENT.md) for how to get started with
317
+ See the [Development Guide](CONTRIBUTING.md) for how to get started with
318
318
  development on the ChefDK itself, as well as details on how dependencies,
319
319
  packaging, and building works.
320
320
 
data/Rakefile CHANGED
@@ -63,7 +63,7 @@ namespace :style do
63
63
  FoodCritic::Rake::LintTask.new(:foodcritic) do |t|
64
64
  t.options = {
65
65
  fail_tags: ["any"],
66
- tags: ["~FC011", "~FC071", "~supermarket"],
66
+ tags: ["~FC071", "~supermarket"],
67
67
  cookbook_paths: ["lib/chef-dk/skeletons/code_generator"],
68
68
  progress: true,
69
69
  }
@@ -12,13 +12,13 @@ GEM
12
12
  addressable (2.5.2)
13
13
  public_suffix (>= 2.0.2, < 4.0)
14
14
  artifactory (2.8.2)
15
- aws-sdk (2.10.44)
16
- aws-sdk-resources (= 2.10.44)
17
- aws-sdk-core (2.10.44)
15
+ aws-sdk (2.10.90)
16
+ aws-sdk-resources (= 2.10.90)
17
+ aws-sdk-core (2.10.90)
18
18
  aws-sigv4 (~> 1.0)
19
19
  jmespath (~> 1.0)
20
- aws-sdk-resources (2.10.44)
21
- aws-sdk-core (= 2.10.44)
20
+ aws-sdk-resources (2.10.90)
21
+ aws-sdk-core (= 2.10.90)
22
22
  aws-sigv4 (1.0.2)
23
23
  berkshelf (6.3.1)
24
24
  buff-config (~> 2.0)
@@ -36,7 +36,6 @@ GEM
36
36
  ridley (~> 5.0)
37
37
  solve (~> 4.0)
38
38
  thor (~> 0.19, < 0.19.2)
39
- blankslate (2.1.2.4)
40
39
  buff-config (2.0.0)
41
40
  buff-extensions (~> 2.0)
42
41
  varia_model (~> 0.6)
@@ -92,9 +91,9 @@ GEM
92
91
  coderay (1.1.2)
93
92
  concurrent-ruby (1.0.5)
94
93
  diff-lcs (1.3)
95
- docker-api (1.33.6)
96
- excon (>= 0.38.0)
97
- json
94
+ docker-api (1.34.0)
95
+ excon (>= 0.47.0)
96
+ multi_json
98
97
  erubis (2.7.0)
99
98
  excon (0.59.0)
100
99
  faraday (0.13.1)
@@ -108,12 +107,12 @@ GEM
108
107
  gyoku (1.3.1)
109
108
  builder (>= 2.1.2)
110
109
  hashie (3.5.6)
111
- highline (1.7.8)
110
+ highline (1.7.10)
112
111
  hitimes (1.2.6)
113
112
  htmlentities (4.3.4)
114
113
  httpclient (2.8.3)
115
114
  iniparse (1.4.4)
116
- inspec (1.36.1)
115
+ inspec (1.45.13)
117
116
  addressable (~> 2.4)
118
117
  faraday (>= 0.9.0)
119
118
  hashie (~> 3.4)
@@ -131,8 +130,8 @@ GEM
131
130
  semverse
132
131
  sslshake (~> 1.2)
133
132
  thor (~> 0.19)
134
- toml (~> 0.1)
135
- train (~> 0.26)
133
+ tomlrb (~> 1.2)
134
+ train (~> 0.29, >= 0.29.2)
136
135
  ipaddress (0.8.3)
137
136
  jmespath (1.3.1)
138
137
  json (2.1.0)
@@ -142,7 +141,7 @@ GEM
142
141
  multi_json
143
142
  retryable (~> 2.0)
144
143
  test-kitchen (~> 1.4, >= 1.4.1)
145
- kitchen-inspec (0.19.0)
144
+ kitchen-inspec (0.20.0)
146
145
  hashie (~> 3.4)
147
146
  inspec (>= 0.34.0, < 2.0.0)
148
147
  test-kitchen (~> 1.6)
@@ -153,7 +152,7 @@ GEM
153
152
  logging (2.2.2)
154
153
  little-plugger (~> 1.1)
155
154
  multi_json (~> 1.10)
156
- method_source (0.8.2)
155
+ method_source (0.9.0)
157
156
  minitar (0.6.1)
158
157
  mixlib-archive (0.4.1)
159
158
  mixlib-log
@@ -167,7 +166,7 @@ GEM
167
166
  mixlib-log (1.7.1)
168
167
  mixlib-shellout (2.3.2)
169
168
  mixlib-versioning (1.2.2)
170
- molinillo (0.6.3)
169
+ molinillo (0.6.4)
171
170
  multi_json (1.12.2)
172
171
  multipart-post (2.0.0)
173
172
  net-scp (1.2.1)
@@ -185,7 +184,7 @@ GEM
185
184
  nori (2.6.0)
186
185
  octokit (4.7.0)
187
186
  sawyer (~> 0.8.0, >= 0.5.3)
188
- ohai (8.24.1)
187
+ ohai (8.25.1)
189
188
  chef-config (>= 12.5.0.alpha.1, < 14)
190
189
  ffi (~> 1.9)
191
190
  ffi-yajl (~> 2.2)
@@ -198,15 +197,13 @@ GEM
198
197
  systemu (~> 2.6.4)
199
198
  wmi-lite (~> 1.0)
200
199
  parallel (1.12.0)
201
- parslet (1.5.0)
202
- blankslate (~> 2.0)
200
+ parslet (1.8.1)
203
201
  plist (3.3.0)
204
202
  proxifier (1.0.3)
205
- pry (0.10.4)
203
+ pry (0.11.3)
206
204
  coderay (~> 1.1.0)
207
- method_source (~> 0.8.1)
208
- slop (~> 3.4)
209
- public_suffix (3.0.0)
205
+ method_source (~> 0.9.0)
206
+ public_suffix (3.0.1)
210
207
  rack (1.6.8)
211
208
  rainbow (2.1.0)
212
209
  retryable (2.0.4)
@@ -254,17 +251,16 @@ GEM
254
251
  addressable (>= 2.3.5, < 2.6)
255
252
  faraday (~> 0.8, < 1.0)
256
253
  semverse (2.0.0)
257
- serverspec (2.40.0)
254
+ serverspec (2.41.3)
258
255
  multi_json
259
256
  rspec (~> 3.0)
260
257
  rspec-its
261
- specinfra (~> 2.68)
258
+ specinfra (~> 2.72)
262
259
  sfl (2.3)
263
- slop (3.6.0)
264
260
  solve (4.0.0)
265
261
  molinillo (~> 0.6)
266
262
  semverse (>= 1.1, < 3.0)
267
- specinfra (2.71.2)
263
+ specinfra (2.72.1)
268
264
  net-scp
269
265
  net-ssh (>= 2.7, < 5.0)
270
266
  net-telnet
@@ -283,9 +279,8 @@ GEM
283
279
  thor (0.19.1)
284
280
  timers (4.0.4)
285
281
  hitimes
286
- toml (0.1.2)
287
- parslet (~> 1.5.0)
288
- train (0.26.2)
282
+ tomlrb (1.2.6)
283
+ train (0.29.2)
289
284
  docker-api (~> 1.26)
290
285
  json (>= 1.8, < 3.0)
291
286
  mixlib-shellout (~> 2.0)
@@ -311,7 +306,7 @@ GEM
311
306
  winrm-elevated (1.1.0)
312
307
  winrm (~> 2.0)
313
308
  winrm-fs (~> 1.0)
314
- winrm-fs (1.0.1)
309
+ winrm-fs (1.1.1)
315
310
  erubis (~> 2.7)
316
311
  logging (>= 1.6.1, < 3.0)
317
312
  rubyzip (~> 1.1)
@@ -336,4 +331,4 @@ DEPENDENCIES
336
331
  winrm-fs
337
332
 
338
333
  BUNDLED WITH
339
- 1.15.4
334
+ 1.16.0
@@ -0,0 +1,73 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2017 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "chef/server_api"
19
+
20
+ module ChefDK
21
+
22
+ # A wrapper for `Chef::ServerAPI` that supports multi-threading by creating a
23
+ # `Chef::ServerAPI` object per-thread.
24
+ #
25
+ # This is intended to be used for downloading cookbooks from the Chef Server,
26
+ # where the API of the Chef Server requires each file to be downloaded
27
+ # individually.
28
+ #
29
+ # It also configures `Chef::ServerAPI` to enable keepalives by default. To
30
+ # disable them, `keepalives: false` must be set in the options to the
31
+ # constructor.
32
+ class ChefServerAPIMulti
33
+
34
+ KEEPALIVES_TRUE = { keepalives: true }.freeze
35
+
36
+ attr_reader :url
37
+ attr_reader :opts
38
+
39
+ def initialize(url, opts)
40
+ @url = url
41
+ @opts = KEEPALIVES_TRUE.merge(opts)
42
+ end
43
+
44
+ def head(*args)
45
+ client_for_thread.head(*args)
46
+ end
47
+
48
+ def get(*args)
49
+ client_for_thread.get(*args)
50
+ end
51
+
52
+ def put(*args)
53
+ client_for_thread.put(*args)
54
+ end
55
+
56
+ def post(*args)
57
+ client_for_thread.post(*args)
58
+ end
59
+
60
+ def delete(*args)
61
+ client_for_thread.delete(*args)
62
+ end
63
+
64
+ def streaming_request(*args, &block)
65
+ client_for_thread.streaming_request(*args, &block)
66
+ end
67
+
68
+ def client_for_thread
69
+ Thread.current[:chef_server_api_multi] ||= Chef::ServerAPI.new(@url, @opts)
70
+ end
71
+
72
+ end
73
+ end
@@ -29,16 +29,16 @@ module ChefDK
29
29
  include Configurable
30
30
 
31
31
  banner(<<-BANNER)
32
- Usage: chef update [ POLICY_FILE ] [options]
32
+ Usage: chef update [ POLICY_FILE ] [options] [cookbook_1] [...]
33
33
 
34
34
  `chef update` reads your `Policyfile.rb`, applies any changes, re-solves the
35
35
  dependencies and emits an updated `Policyfile.lock.json`. The new locked policy
36
36
  will reflect any changes to the `run_list` and pull in any cookbook updates
37
37
  that are compatible with the version constraints stated in your `Policyfile.rb`.
38
38
 
39
- NOTE: `chef update` does not yet support granular updates (e.g., just updating
40
- the `run_list` or a specific cookbook version). Support will be added in a
41
- future version.
39
+ Individual dependent cookbooks (and their dependencies) may be updated by
40
+ passing their names after the POLICY_FILE. The POLICY_FILE parameter is
41
+ mandatory if you want to update individual cookbooks.
42
42
 
43
43
  See our detailed README for more information:
44
44
 
@@ -83,13 +83,6 @@ BANNER
83
83
 
84
84
  def run(params = [])
85
85
  return 1 unless apply_params!(params)
86
-
87
- # Force config file to be loaded. We don't use the configuration
88
- # directly, but the user may have SSL configuration options that they
89
- # need to talk to a private supermarket (e.g., trusted_certs or
90
- # ssl_verify_mode)
91
- chef_config
92
-
93
86
  attributes_updater.run
94
87
  installer.run(@cookbooks_to_update) unless update_attributes_only?
95
88
  0
@@ -104,7 +97,7 @@ BANNER
104
97
 
105
98
  def attributes_updater
106
99
  @attributes_updater ||=
107
- PolicyfileServices::UpdateAttributes.new(policyfile: policyfile_relative_path, ui: ui, root_dir: Dir.pwd)
100
+ PolicyfileServices::UpdateAttributes.new(policyfile: policyfile_relative_path, ui: ui, root_dir: Dir.pwd, chef_config: chef_config)
108
101
  end
109
102
 
110
103
  def debug?
@@ -18,6 +18,9 @@
18
18
  require "chef/config"
19
19
  require "chef/workstation_config_loader"
20
20
 
21
+ require "chef-dk/cookbook_omnifetch"
22
+ require "chef-dk/chef_server_api_multi"
23
+
21
24
  # Define a config context for ChefDK
22
25
  class Chef::Config
23
26
 
@@ -48,6 +51,8 @@ module ChefDK
48
51
  return @chef_config if @chef_config
49
52
  config_loader.load
50
53
  @chef_config = Chef::Config
54
+ CookbookOmnifetch.integration.default_chef_server_http_client = default_chef_server_http_client
55
+ @chef_config
51
56
  end
52
57
 
53
58
  def chefdk_config
@@ -65,5 +70,19 @@ module ChefDK
65
70
  def knife_config
66
71
  chef_config.knife
67
72
  end
73
+
74
+ def reset_config!
75
+ @chef_config = nil
76
+ @config_loader = nil
77
+ end
78
+
79
+ def default_chef_server_http_client
80
+ lambda do
81
+ ChefServerAPIMulti.new(@chef_config.chef_server_url,
82
+ signing_key_filename: @chef_config.client_key,
83
+ client_name: @chef_config.node_name)
84
+ end
85
+ end
86
+
68
87
  end
69
88
  end
@@ -28,4 +28,5 @@ CookbookOmnifetch.configure do |c|
28
28
  c.storage_path = Pathname.new(File.expand_path(File.join(ChefDK::Helpers.chefdk_home, "cache", "cookbooks")))
29
29
  c.shell_out_class = ChefDK::ShellOut
30
30
  c.cached_cookbook_class = ChefDK::CookbookMetadata
31
+ c.chef_server_download_concurrency = 10
31
32
  end
@@ -96,6 +96,9 @@ module ChefDK
96
96
  class BUG < RuntimeError
97
97
  end
98
98
 
99
+ class IncludePolicyCookbookSourceConflict < StandardError
100
+ end
101
+
99
102
  class CookbookSourceConflict < StandardError
100
103
 
101
104
  attr_reader :conflicting_cookbooks
@@ -136,4 +139,12 @@ EXAMPLE
136
139
 
137
140
  end
138
141
 
142
+ class PolicyfileLockDownloadError < StandardError
143
+ end
144
+
145
+ class LocalPolicyfileLockNotFound < StandardError
146
+ end
147
+
148
+ class InvalidPolicyfileLocation < StandardError
149
+ end
139
150
  end
@@ -154,7 +154,7 @@ EOH
154
154
  end
155
155
  if comment
156
156
  # Ensure there's no trailing whitespace
157
- result.gsub(/^(.+)$/, "#{comment} \\1").gsub(/^$/, "#{comment}")
157
+ result.gsub(/^(.+)$/, "#{comment} \\1").gsub(/^$/, "#{comment}").strip
158
158
  else
159
159
  result
160
160
  end
@@ -0,0 +1,110 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2017 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "chef/mash"
19
+
20
+ module ChefDK
21
+ module Policyfile
22
+ class AttributeMergeChecker
23
+ # A ConflictError is used to specify a conflict has occurred
24
+ class ConflictError < StandardError
25
+ attr_reader :attribute_path
26
+ attr_reader :provided_by
27
+
28
+ def initialize(attribute_path, provided_by)
29
+ @attribute_path = attribute_path
30
+ @provided_by = provided_by
31
+ super("Attribute '#{attribute_path}' provided conflicting values by the following sources #{provided_by}")
32
+ end
33
+ end
34
+
35
+ # A Leaf is used to mark an individual attribute that has already
36
+ # been provided, along with its value and by who
37
+ #
38
+ # @api private
39
+ class Leaf
40
+ attr_reader :provided_by
41
+ attr_reader :val
42
+
43
+ def initialize(provided_by, val)
44
+ @provided_by = provided_by
45
+ @val = val
46
+ end
47
+ end
48
+
49
+ # An AttributeHashInfo holds a set of attributes along with where they came from
50
+ class AttributeHashInfo
51
+ attr_reader :source_name
52
+ attr_reader :hash
53
+ def initialize(source_name, hash)
54
+ @source_name = source_name
55
+ @hash = hash
56
+ end
57
+ end
58
+
59
+ # @return [Array<AttributeHashInfo>] A list of attributes and who they were provided by
60
+ attr_reader :attribute_hash_infos
61
+
62
+ def initialize
63
+ @attribute_hash_infos = []
64
+ end
65
+
66
+ # Add a hash of attributes to the set of attributes that will be compared
67
+ # for conflicts
68
+ #
69
+ # @param source_name [String] Where the attributes came from
70
+ # @param hash [Hash] attributes from source_name
71
+ def with_attributes(source_name, hash)
72
+ attribute_hash_infos << AttributeHashInfo.new(source_name, hash)
73
+ end
74
+
75
+ # Check all added attributes for conflicts. Different sources can provide
76
+ # the same attribute if they have the same value. Otherwise, it is considered
77
+ # a conflict
78
+ #
79
+ # @raise ConflictError if there are conflicting attributes
80
+ def check!
81
+ check_struct = Mash.new
82
+ attribute_hash_infos.each do |attr_hash_info|
83
+ fill!(check_struct, attr_hash_info.source_name, "", attr_hash_info.hash)
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def fill!(acc, source_name, path, hash)
90
+ hash.each do |(key, val)|
91
+ new_path = "#{path}[#{key}]"
92
+ if val.kind_of?(Hash)
93
+ acc[key] ||= Mash.new
94
+ fill!(acc[key], source_name, new_path, val)
95
+ else
96
+ if acc[key].nil?
97
+ acc[key] = Leaf.new(source_name, val)
98
+ else
99
+ leaf = acc[key]
100
+ if leaf.val != val
101
+ raise ConflictError.new(new_path, [leaf.provided_by, source_name])
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ end
109
+ end
110
+ end