chef-dk 2.3.4 → 2.4.17

Sign up to get free protection for your applications and to get access to all the features.
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