chef 12.11.18 → 12.12.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/Rakefile +3 -2
  4. data/VERSION +1 -1
  5. data/acceptance/Gemfile.lock +22 -23
  6. data/acceptance/data-collector/test/integration/default/serverspec/default_spec.rb +2 -41
  7. data/lib/chef/application/solo.rb +7 -0
  8. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +1 -1
  9. data/lib/chef/data_collector.rb +79 -43
  10. data/lib/chef/data_collector/messages.rb +4 -33
  11. data/lib/chef/data_collector/messages/helpers.rb +2 -2
  12. data/lib/chef/data_collector/resource_report.rb +21 -11
  13. data/lib/chef/decorator/unchain.rb +43 -0
  14. data/lib/chef/exceptions.rb +5 -0
  15. data/lib/chef/http.rb +5 -5
  16. data/lib/chef/knife/cookbook_create.rb +4 -0
  17. data/lib/chef/knife/cookbook_site_download.rb +8 -1
  18. data/lib/chef/knife/cookbook_site_install.rb +8 -0
  19. data/lib/chef/knife/cookbook_site_list.rb +8 -1
  20. data/lib/chef/knife/cookbook_site_search.rb +8 -1
  21. data/lib/chef/knife/cookbook_site_share.rb +8 -1
  22. data/lib/chef/knife/cookbook_site_show.rb +14 -3
  23. data/lib/chef/knife/cookbook_site_unshare.rb +8 -1
  24. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  25. data/lib/chef/knife/supermarket_download.rb +33 -0
  26. data/lib/chef/knife/supermarket_install.rb +33 -0
  27. data/lib/chef/knife/supermarket_list.rb +33 -0
  28. data/lib/chef/knife/supermarket_search.rb +33 -0
  29. data/lib/chef/knife/supermarket_share.rb +33 -0
  30. data/lib/chef/knife/supermarket_show.rb +33 -0
  31. data/lib/chef/knife/supermarket_unshare.rb +33 -0
  32. data/lib/chef/node.rb +13 -32
  33. data/lib/chef/node/attribute.rb +123 -70
  34. data/lib/chef/node/attribute_collections.rb +9 -130
  35. data/lib/chef/node/common_api.rb +124 -0
  36. data/lib/chef/node/immutable_collections.rb +27 -2
  37. data/lib/chef/property.rb +6 -2
  38. data/lib/chef/provider.rb +4 -5
  39. data/lib/chef/provider/batch.rb +1 -1
  40. data/lib/chef/provider/directory.rb +3 -1
  41. data/lib/chef/provider/package/openbsd.rb +1 -1
  42. data/lib/chef/provider/package/rubygems.rb +9 -3
  43. data/lib/chef/provider/package/windows/exe.rb +2 -5
  44. data/lib/chef/provider/powershell_script.rb +1 -1
  45. data/lib/chef/provider/remote_directory.rb +2 -0
  46. data/lib/chef/resource.rb +22 -17
  47. data/lib/chef/resource_builder.rb +9 -4
  48. data/lib/chef/shell.rb +1 -1
  49. data/lib/chef/version.rb +1 -1
  50. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +2 -4
  51. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +2 -3
  52. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -2
  53. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -2
  54. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +2 -3
  55. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +2 -3
  56. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +2 -3
  57. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +2 -3
  58. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +2 -3
  59. data/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg +0 -0
  60. data/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg +0 -0
  61. data/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg +0 -0
  62. data/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg +0 -0
  63. data/spec/functional/resource/dsc_script_spec.rb +1 -0
  64. data/spec/functional/resource/package_spec.rb +1 -1
  65. data/spec/functional/resource/template_spec.rb +3 -3
  66. data/spec/functional/shell_spec.rb +1 -1
  67. data/spec/integration/knife/client_bulk_delete_spec.rb +130 -0
  68. data/spec/integration/knife/client_create_spec.rb +69 -0
  69. data/spec/integration/knife/client_delete_spec.rb +63 -0
  70. data/spec/integration/knife/client_key_create_spec.rb +65 -0
  71. data/spec/integration/knife/client_key_delete_spec.rb +42 -0
  72. data/spec/integration/knife/client_key_list_spec.rb +60 -0
  73. data/spec/integration/knife/client_key_show_spec.rb +44 -0
  74. data/spec/integration/knife/client_list_spec.rb +48 -0
  75. data/spec/integration/knife/client_show_spec.rb +36 -0
  76. data/spec/integration/knife/cookbook_bulk_delete_spec.rb +64 -0
  77. data/spec/integration/knife/cookbook_download_spec.rb +95 -0
  78. data/spec/integration/knife/cookbook_list_spec.rb +54 -0
  79. data/spec/integration/knife/cookbook_show_spec.rb +159 -0
  80. data/spec/integration/knife/cookbook_upload_spec.rb +90 -0
  81. data/spec/integration/knife/data_bag_create_spec.rb +58 -0
  82. data/spec/integration/knife/data_bag_delete_spec.rb +58 -0
  83. data/spec/integration/knife/data_bag_from_file_spec.rb +115 -0
  84. data/spec/integration/knife/data_bag_list_spec.rb +43 -0
  85. data/spec/integration/knife/data_bag_show_spec.rb +53 -0
  86. data/spec/integration/knife/environment_compare_spec.rb +74 -0
  87. data/spec/integration/knife/environment_create_spec.rb +40 -0
  88. data/spec/integration/knife/environment_delete_spec.rb +36 -0
  89. data/spec/integration/knife/environment_from_file_spec.rb +115 -0
  90. data/spec/integration/knife/environment_list_spec.rb +41 -0
  91. data/spec/integration/knife/environment_show_spec.rb +56 -0
  92. data/spec/integration/knife/node_bulk_delete_spec.rb +51 -0
  93. data/spec/integration/knife/node_create_spec.rb +46 -0
  94. data/spec/integration/knife/node_delete_spec.rb +47 -0
  95. data/spec/integration/knife/node_environment_set_spec.rb +42 -0
  96. data/spec/integration/knife/node_from_file_spec.rb +58 -0
  97. data/spec/integration/knife/node_list_spec.rb +44 -0
  98. data/spec/integration/knife/node_run_list_add_spec.rb +53 -0
  99. data/spec/integration/knife/node_run_list_remove_spec.rb +35 -0
  100. data/spec/integration/knife/node_run_list_set_spec.rb +40 -0
  101. data/spec/integration/knife/node_show_spec.rb +35 -0
  102. data/spec/integration/knife/role_bulk_delete_spec.rb +51 -0
  103. data/spec/integration/knife/role_create_spec.rb +40 -0
  104. data/spec/integration/knife/role_delete_spec.rb +47 -0
  105. data/spec/integration/knife/role_from_file_spec.rb +95 -0
  106. data/spec/integration/knife/role_list_spec.rb +44 -0
  107. data/spec/integration/knife/role_show_spec.rb +50 -0
  108. data/spec/support/shared/integration/knife_support.rb +10 -3
  109. data/spec/unit/application/solo_spec.rb +7 -0
  110. data/spec/unit/cookbook_version_spec.rb +4 -4
  111. data/spec/unit/data_collector/messages/helpers_spec.rb +3 -7
  112. data/spec/unit/data_collector/messages_spec.rb +28 -45
  113. data/spec/unit/data_collector_spec.rb +40 -47
  114. data/spec/unit/knife/cookbook_create_spec.rb +1 -0
  115. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -0
  116. data/spec/unit/knife/node_environment_set_spec.rb +0 -24
  117. data/spec/unit/knife/node_run_list_set_spec.rb +0 -25
  118. data/spec/unit/node/attribute_spec.rb +7 -9
  119. data/spec/unit/node/immutable_collections_spec.rb +4 -0
  120. data/spec/unit/node/vivid_mash_spec.rb +344 -0
  121. data/spec/unit/node_spec.rb +115 -26
  122. data/spec/unit/provider/directory_spec.rb +11 -1
  123. data/spec/unit/provider/package/windows/exe_spec.rb +14 -9
  124. data/spec/unit/provider/powershell_script_spec.rb +4 -4
  125. data/spec/unit/provider/remote_directory_spec.rb +15 -0
  126. data/spec/unit/recipe_spec.rb +31 -6
  127. data/spec/unit/run_context_spec.rb +2 -2
  128. data/spec/unit/shell/shell_session_spec.rb +1 -1
  129. data/tasks/dependencies.rb +0 -2
  130. metadata +55 -786
  131. data/acceptance/.bundle/config +0 -2
  132. data/acceptance/basics/.kitchen/logs/chef-current-install-ubuntu-1404.log +0 -2
  133. data/acceptance/basics/.kitchen/logs/kitchen.log +0 -3
  134. data/acceptance/fips/.kitchen/logs/fips-integration-centos-6.log +0 -3
  135. data/acceptance/fips/.kitchen/logs/fips-integration-windows-2012r2.log +0 -3
  136. data/acceptance/fips/.kitchen/logs/fips-unit-functional-centos-6.log +0 -3
  137. data/acceptance/fips/.kitchen/logs/fips-unit-functional-windows-2012r2.log +0 -3
  138. data/acceptance/fips/.kitchen/logs/kitchen.log +0 -6
  139. data/acceptance/trivial/.kitchen/logs/chef-current-install-windows-2012r2.log +0 -2
  140. data/acceptance/trivial/.kitchen/logs/kitchen.log +0 -3
  141. data/acceptance/windows-service/.kitchen/logs/chef-windows-service-windows-2012r2.log +0 -2
  142. data/acceptance/windows-service/.kitchen/logs/kitchen.log +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97b8d731ca0f6c028fb862f811e120dc265d5228
4
- data.tar.gz: 3f3192a78b9d23a2536c9e911140fbeb19ed9a79
3
+ metadata.gz: 06fd3e81e49974a9b3c27291e92c045abf414b17
4
+ data.tar.gz: 6e798ffc8280bf201dd883f03b4d046dfa95be9c
5
5
  SHA512:
6
- metadata.gz: 5154122e67402dc45487bda181cc291e1599b3fc8ccc0fba240400386c8ccdc38be2bca97a4b6734dfe4000606401382e5ac3aa851cc4ea0ede9f8e54e9eb1b6
7
- data.tar.gz: c1c519e59a74cae11a8de2b316d14ee1a9725f5b4608a4e31aeafbcfaa2d14f67103684b3ba068b811ea412595d8916d77cf2a3aedeb91e46ac89251455bf5f3
6
+ metadata.gz: cbb907b8556c4dff3c85e589722e048af0ae070057f5338845f2105ec3b14efe55cdd24042342bf358aff2c43e2390189ab0b8a2f4e3a174daf2191347d009e2
7
+ data.tar.gz: 5353be5018040d24332f63f96e0bea3ca85f7cc49bf5468ccbfd154b9d6c3335610c38e0bc8163f8ab721ffddaa1f33dd7d918780f1ae5dbde4d56122b7d000f
data/Gemfile CHANGED
@@ -13,15 +13,15 @@ gem "chef", path: "."
13
13
 
14
14
  gem "chef-config", path: File.expand_path("../chef-config", __FILE__) if File.exist?(File.expand_path("../chef-config", __FILE__))
15
15
  # Ensure that we can always install rake, regardless of gem groups
16
- gem "rake"
16
+ gem "rake", group: [ :default, :omnibus_package, :development ]
17
17
  gem "bundler"
18
18
  gem "cheffish"
19
19
 
20
20
  group(:omnibus_package) do
21
21
  gem "appbundler"
22
22
  gem "rb-readline"
23
- gem "nokogiri"
24
23
  end
24
+
25
25
  group(:omnibus_package, :pry) do
26
26
  gem "pry"
27
27
  gem "pry-byebug"
@@ -65,7 +65,7 @@ end
65
65
 
66
66
  group(:development, :test) do
67
67
  gem "simplecov"
68
- gem "rack"
68
+ gem "rack", "< 2.0" # 2.0 requires Ruby 2.2+
69
69
 
70
70
  # for testing new chefstyle rules
71
71
  # gem 'chefstyle', github: 'chef/chefstyle'
@@ -78,7 +78,7 @@ end
78
78
 
79
79
  group(:travis) do
80
80
  # See `bundler-audit` in .travis.yml
81
- gem "bundler-audit", git: "https://github.com/rubysec/bundler-audit.git", ref: "4e32fca"
81
+ gem "bundler-audit", git: "https://github.com/rubysec/bundler-audit.git"
82
82
  end
83
83
 
84
84
  instance_eval(ENV["GEMFILE_MOD"]) if ENV["GEMFILE_MOD"]
data/Rakefile CHANGED
@@ -29,12 +29,13 @@ require_relative "tasks/cbgb"
29
29
  require_relative "tasks/dependencies"
30
30
  require_relative "tasks/changelog"
31
31
 
32
- ChefConfig::PackageTask.new(File.expand_path("..", __FILE__), "Chef") do |package|
32
+ ChefConfig::PackageTask.new(File.expand_path("..", __FILE__), "Chef", "chef") do |package|
33
33
  package.component_paths = ["chef-config"]
34
34
  package.generate_version_class = true
35
35
  end
36
36
  # Add a conservative dependency update to version:bump (which was created by PackageTask)
37
- task "version:bump" => %w{version:bump_patch version:update bundle:install}
37
+ task "version:bump" => %w{version:bump_patch version:update}
38
+ task "version:bump" => %w{version:bump_patch version:update}
38
39
 
39
40
  task :pedant, :chef_zero_spec
40
41
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 12.11.18
1
+ 12.12.13
@@ -11,13 +11,13 @@ GEM
11
11
  specs:
12
12
  addressable (2.4.0)
13
13
  artifactory (2.3.2)
14
- aws-sdk (2.3.9)
15
- aws-sdk-resources (= 2.3.9)
16
- aws-sdk-core (2.3.9)
14
+ aws-sdk (2.3.14)
15
+ aws-sdk-resources (= 2.3.14)
16
+ aws-sdk-core (2.3.14)
17
17
  jmespath (~> 1.0)
18
- aws-sdk-resources (2.3.9)
19
- aws-sdk-core (= 2.3.9)
20
- berkshelf (4.3.3)
18
+ aws-sdk-resources (2.3.14)
19
+ aws-sdk-core (= 2.3.14)
20
+ berkshelf (4.3.5)
21
21
  addressable (~> 2.3, >= 2.3.4)
22
22
  berkshelf-api-client (~> 2.0, >= 2.0.2)
23
23
  buff-config (~> 1.0)
@@ -29,6 +29,7 @@ GEM
29
29
  faraday (~> 0.9)
30
30
  httpclient (~> 2.7)
31
31
  minitar (~> 0.5, >= 0.5.4)
32
+ mixlib-archive (~> 0.1)
32
33
  octokit (~> 4.0)
33
34
  retryable (~> 2.0)
34
35
  ridley (~> 4.5)
@@ -52,7 +53,7 @@ GEM
52
53
  celluloid-io (0.16.2)
53
54
  celluloid (>= 0.16.0)
54
55
  nio4r (>= 1.1.0)
55
- chef-config (12.10.24)
56
+ chef-config (12.11.18)
56
57
  fuzzyurl (~> 0.8.0)
57
58
  mixlib-config (~> 2.0)
58
59
  mixlib-shellout (~> 2.0)
@@ -75,17 +76,17 @@ GEM
75
76
  hashie (3.4.4)
76
77
  hitimes (1.2.4)
77
78
  httpclient (2.7.2)
78
- inspec (0.22.1)
79
+ inspec (0.26.0)
79
80
  hashie (~> 3.4)
80
81
  json (~> 1.8)
81
82
  method_source (~> 0.8)
82
83
  pry (~> 0)
83
- r-train (~> 0.12)
84
84
  rainbow (~> 2)
85
85
  rspec (~> 3)
86
86
  rspec-its (~> 1.2)
87
87
  rubyzip (~> 1.1)
88
88
  thor (~> 0.19)
89
+ train (~> 0.13)
89
90
  jmespath (1.2.4)
90
91
  json_pure (>= 1.8.1)
91
92
  json (1.8.3)
@@ -107,13 +108,11 @@ GEM
107
108
  multi_json (~> 1.10)
108
109
  method_source (0.8.2)
109
110
  minitar (0.5.4)
110
- mixlib-authentication (1.4.0)
111
+ mixlib-archive (0.1.0)
112
+ mixlib-authentication (1.4.1)
111
113
  mixlib-log
112
- rspec-core (~> 3.2)
113
- rspec-expectations (~> 3.2)
114
- rspec-mocks (~> 3.2)
115
114
  mixlib-config (2.2.1)
116
- mixlib-install (1.0.12)
115
+ mixlib-install (1.0.13)
117
116
  artifactory
118
117
  mixlib-shellout
119
118
  mixlib-versioning
@@ -134,14 +133,6 @@ GEM
134
133
  coderay (~> 1.1.0)
135
134
  method_source (~> 0.8.1)
136
135
  slop (~> 3.4)
137
- r-train (0.12.1)
138
- docker-api (~> 1.26)
139
- json (~> 1.8)
140
- mixlib-shellout (~> 2.0)
141
- net-scp (~> 1.2)
142
- net-ssh (>= 2.9, < 4.0)
143
- winrm (~> 1.6)
144
- winrm-fs (~> 0.3)
145
136
  rainbow (2.1.0)
146
137
  retryable (2.0.3)
147
138
  ridley (4.5.1)
@@ -189,7 +180,7 @@ GEM
189
180
  solve (2.0.3)
190
181
  molinillo (~> 0.4.2)
191
182
  semverse (~> 1.1)
192
- test-kitchen (1.9.0)
183
+ test-kitchen (1.9.2)
193
184
  mixlib-install (~> 1.0, >= 1.0.4)
194
185
  mixlib-shellout (>= 1.2, < 3.0)
195
186
  net-scp (~> 1.1)
@@ -199,6 +190,14 @@ GEM
199
190
  thor (0.19.1)
200
191
  timers (4.0.4)
201
192
  hitimes
193
+ train (0.13.1)
194
+ docker-api (~> 1.26)
195
+ json (~> 1.8)
196
+ mixlib-shellout (~> 2.0)
197
+ net-scp (~> 1.2)
198
+ net-ssh (>= 2.9, < 4.0)
199
+ winrm (~> 1.6)
200
+ winrm-fs (~> 0.3)
202
201
  varia_model (0.4.1)
203
202
  buff-extensions (~> 1.0)
204
203
  hashie (>= 2.0.2, < 4.0.0)
@@ -110,6 +110,7 @@ shared_examples_for "run_converge.success payload check" do
110
110
  expanded_run_list
111
111
  message_type
112
112
  message_version
113
+ node
113
114
  node_name
114
115
  organization_name
115
116
  resources
@@ -150,6 +151,7 @@ shared_examples_for "run_converge.failure payload check" do
150
151
  expanded_run_list
151
152
  message_type
152
153
  message_version
154
+ node
153
155
  node_name
154
156
  organization_name
155
157
  resources
@@ -178,44 +180,6 @@ shared_examples_for "run_converge.failure payload check" do
178
180
  end
179
181
  end
180
182
 
181
- shared_examples_for "node-update payload check" do
182
- describe "node update message" do
183
- let(:required_fields) do
184
- %w{
185
- entity_name
186
- entity_type
187
- entity_uuid
188
- id
189
- message_type
190
- message_version
191
- organization_name
192
- recorded_at
193
- remote_hostname
194
- requestor_name
195
- requestor_type
196
- run_id
197
- service_hostname
198
- source
199
- task
200
- user_agent
201
- }
202
- end
203
- let(:optional_fields) { %{data} }
204
-
205
- it "is not missing any required fields" do
206
- payload = JSON.load(command("curl http://localhost:9292/cache/action").stdout)
207
- missing_fields = required_fields.select { |key| !payload.key?(key) }
208
- expect(missing_fields).to eq([])
209
- end
210
-
211
- it "does not have any extra fields" do
212
- payload = JSON.load(command("curl http://localhost:9292/cache/action").stdout)
213
- extra_fields = payload.keys.select { |key| !required_fields.include?(key) && !optional_fields.include?(key) }
214
- expect(extra_fields).to eq([])
215
- end
216
- end
217
- end
218
-
219
183
  describe "CCR with no data collector URL configured" do
220
184
  include_examples "successful chef run", "chef-client -z -c /etc/chef/no-endpoint.rb"
221
185
  include_examples "counter checks", { "run_start" => nil, "run_converge.success" => nil, "run_converge.failure" => nil }
@@ -226,7 +190,6 @@ describe "CCR, local mode, config in solo mode" do
226
190
  include_examples "counter checks", { "run_start" => 1, "run_converge.success" => 1, "run_converge.failure" => nil }
227
191
  include_examples "run_start payload check"
228
192
  include_examples "run_converge.success payload check"
229
- include_examples "node-update payload check"
230
193
  end
231
194
 
232
195
  describe "CCR, local mode, config in client mode" do
@@ -239,7 +202,6 @@ describe "CCR, local mode, config in both mode" do
239
202
  include_examples "counter checks", { "run_start" => 1, "run_converge.success" => 1, "run_converge.failure" => nil }
240
203
  include_examples "run_start payload check"
241
204
  include_examples "run_converge.success payload check"
242
- include_examples "node-update payload check"
243
205
  end
244
206
 
245
207
  describe "CCR, local mode, config in solo mode, failed run" do
@@ -247,5 +209,4 @@ describe "CCR, local mode, config in solo mode, failed run" do
247
209
  include_examples "counter checks", { "run_start" => 1, "run_converge.success" => nil, "run_converge.failure" => 1 }
248
210
  include_examples "run_start payload check"
249
211
  include_examples "run_converge.failure payload check"
250
- include_examples "node-update payload check"
251
212
  end
@@ -241,6 +241,13 @@ class Chef::Application::Solo < Chef::Application
241
241
  ARGV[dash_r] = "--recipe-url"
242
242
  end
243
243
 
244
+ # For back compat reasons, we need to ensure that we try and use the cache_path as a repo first
245
+ Chef::Log.debug "Current chef_repo_path is #{Chef::Config.chef_repo_path}"
246
+
247
+ if !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
248
+ Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Chef::Config[:cache_path])
249
+ end
250
+
244
251
  Chef::Config[:local_mode] = true
245
252
  else
246
253
  configure_legacy_mode!
@@ -41,7 +41,7 @@ class Chef
41
41
  child_entry = dir.child(name)
42
42
  if child_entry.exists?
43
43
  if result
44
- Chef::Log.debug("Child with name '#{child_entry.name}' found in multiple directories: #{result.parent.path_for_printing} and #{child_entry.parent.path_for_printing}") unless seen[child.name].path_for_printing == child.path_for_printing
44
+ Chef::Log.debug("Child with name '#{child_entry.name}' found in multiple directories: #{result.parent.path_for_printing} and #{child_entry.parent.path_for_printing}")
45
45
  else
46
46
  result = child_entry
47
47
  end
@@ -22,6 +22,7 @@ require "uri"
22
22
  require "chef/event_dispatch/base"
23
23
  require "chef/data_collector/messages"
24
24
  require "chef/data_collector/resource_report"
25
+ require "ostruct"
25
26
 
26
27
  class Chef
27
28
 
@@ -51,13 +52,12 @@ class Chef
51
52
  # and exports its data through a webhook-like mechanism to a configured
52
53
  # endpoint.
53
54
  class Reporter < EventDispatch::Base
54
- attr_reader :updated_resources, :status, :exception, :error_descriptions,
55
- :expanded_run_list, :run_status, :http, :resource_count,
55
+ attr_reader :all_resource_reports, :status, :exception, :error_descriptions,
56
+ :expanded_run_list, :run_context, :run_status, :http,
56
57
  :current_resource_report, :enabled
57
58
 
58
59
  def initialize
59
- @updated_resources = []
60
- @resource_count = 0
60
+ @all_resource_reports = []
61
61
  @current_resource_loaded = nil
62
62
  @error_descriptions = {}
63
63
  @expanded_run_list = {}
@@ -94,6 +94,29 @@ class Chef
94
94
  send_run_completion(status: "failure")
95
95
  end
96
96
 
97
+ # see EventDispatch::Base#converge_start
98
+ # Upon receipt, we stash the run_context for use at the
99
+ # end of the run in order to determine what resource+action
100
+ # combinations have not yet fired so we can report on
101
+ # unprocessed resources.
102
+ def converge_start(run_context)
103
+ @run_context = run_context
104
+ end
105
+
106
+ # see EventDispatch::Base#converge_complete
107
+ # At the end of the converge, we add any unprocessed resources
108
+ # to our report list.
109
+ def converge_complete
110
+ detect_unprocessed_resources
111
+ end
112
+
113
+ # see EventDispatch::Base#converge_failed
114
+ # At the end of the converge, we add any unprocessed resources
115
+ # to our report list
116
+ def converge_failed(exception)
117
+ detect_unprocessed_resources
118
+ end
119
+
97
120
  # see EventDispatch::Base#resource_current_state_loaded
98
121
  # Create a new ResourceReport instance that we'll use to track
99
122
  # the state of this resource during the run. Nested resources are
@@ -101,56 +124,40 @@ class Chef
101
124
  # resource, and we only care about tracking top-level resources.
102
125
  def resource_current_state_loaded(new_resource, action, current_resource)
103
126
  return if nested_resource?(new_resource)
104
- update_current_resource_report(
105
- Chef::DataCollector::ResourceReport.new(
106
- new_resource,
107
- action,
108
- current_resource
109
- )
110
- )
127
+ update_current_resource_report(create_resource_report(new_resource, action, current_resource))
111
128
  end
112
129
 
113
130
  # see EventDispatch::Base#resource_up_to_date
114
- # Mark our ResourceReport status accordingly, and increment the total
115
- # resource count.
131
+ # Mark our ResourceReport status accordingly
116
132
  def resource_up_to_date(new_resource, action)
117
133
  current_resource_report.up_to_date unless nested_resource?(new_resource)
118
- increment_resource_count
119
134
  end
120
135
 
121
136
  # see EventDispatch::Base#resource_skipped
122
- # Increment the total resource count. If this is a top-level resource,
123
- # we also create a ResourceReport instance (because a skipped resource
124
- # does not trigger the resource_current_state_loaded event), and flag
125
- # it as skipped.
137
+ # If this is a top-level resource, we create a ResourceReport
138
+ # instance (because a skipped resource does not trigger the
139
+ # resource_current_state_loaded event), and flag it as skipped.
126
140
  def resource_skipped(new_resource, action, conditional)
127
- increment_resource_count
128
141
  return if nested_resource?(new_resource)
129
142
 
130
- update_current_resource_report(
131
- Chef::DataCollector::ResourceReport.new(
132
- new_resource,
133
- action
134
- )
135
- )
136
- current_resource_report.skipped(conditional)
143
+ resource_report = create_resource_report(new_resource, action)
144
+ resource_report.skipped(conditional)
145
+ update_current_resource_report(resource_report)
137
146
  end
138
147
 
139
148
  # see EventDispatch::Base#resource_updated
140
149
  # Flag the current ResourceReport instance as updated (as long as it's
141
- # a top-level resource) and increment the total resource count.
150
+ # a top-level resource).
142
151
  def resource_updated(new_resource, action)
143
152
  current_resource_report.updated unless nested_resource?(new_resource)
144
- increment_resource_count
145
153
  end
146
154
 
147
155
  # see EventDispatch::Base#resource_failed
148
156
  # Flag the current ResourceReport as failed and supply the exception as
149
- # long as it's a top-level resource, increment the total resource count,
150
- # and update the run error text with the proper Formatter.
157
+ # long as it's a top-level resource, and update the run error text
158
+ # with the proper Formatter.
151
159
  def resource_failed(new_resource, action, exception)
152
160
  current_resource_report.failed(exception) unless nested_resource?(new_resource)
153
- increment_resource_count
154
161
  update_error_description(
155
162
  Formatters::ErrorMapper.resource_failed(
156
163
  new_resource,
@@ -161,13 +168,12 @@ class Chef
161
168
  end
162
169
 
163
170
  # see EventDispatch::Base#resource_completed
164
- # Mark the ResourceReport instance as finished (for timing details)
165
- # and add it to the list of resources encountered during this run.
171
+ # Mark the ResourceReport instance as finished (for timing details).
166
172
  # This marks the end of this resource during this run.
167
173
  def resource_completed(new_resource)
168
174
  if current_resource_report && !nested_resource?(new_resource)
169
175
  current_resource_report.finish
170
- add_updated_resource(current_resource_report)
176
+ add_resource_report(current_resource_report)
171
177
  update_current_resource_report(nil)
172
178
  end
173
179
  end
@@ -273,13 +279,11 @@ class Chef
273
279
  # we have nothing to report.
274
280
  return unless run_status
275
281
 
276
- send_to_data_collector(Chef::DataCollector::Messages.node_update_message(run_status).to_json)
277
282
  send_to_data_collector(
278
283
  Chef::DataCollector::Messages.run_end_message(
279
284
  run_status: run_status,
280
285
  expanded_run_list: expanded_run_list,
281
- total_resource_count: resource_count,
282
- updated_resources: updated_resources,
286
+ resources: all_resource_reports,
283
287
  status: opts[:status],
284
288
  error_descriptions: error_descriptions
285
289
  ).to_json
@@ -305,12 +309,12 @@ class Chef
305
309
  Chef::Config[:data_collector][:token]
306
310
  end
307
311
 
308
- def increment_resource_count
309
- @resource_count += 1
310
- end
311
-
312
- def add_updated_resource(resource_report)
313
- @updated_resources << resource_report
312
+ def add_resource_report(resource_report)
313
+ @all_resource_reports << OpenStruct.new(
314
+ resource: resource_report.new_resource,
315
+ action: resource_report.action,
316
+ report_data: resource_report.to_hash
317
+ )
314
318
  end
315
319
 
316
320
  def disable_data_collector_reporter
@@ -333,6 +337,38 @@ class Chef
333
337
  @error_descriptions = discription_hash
334
338
  end
335
339
 
340
+ def create_resource_report(new_resource, action, current_resource = nil)
341
+ Chef::DataCollector::ResourceReport.new(
342
+ new_resource,
343
+ action,
344
+ current_resource
345
+ )
346
+ end
347
+
348
+ def detect_unprocessed_resources
349
+ # create a Set containing all resource+action combinations from
350
+ # the Resource Collection
351
+ collection_resources = Set.new
352
+ run_context.resource_collection.all_resources.each do |resource|
353
+ Array(resource.action).each do |action|
354
+ collection_resources.add([resource, action])
355
+ end
356
+ end
357
+
358
+ # Delete from the Set any resource+action combination we have
359
+ # already processed.
360
+ all_resource_reports.each do |report|
361
+ collection_resources.delete([report.resource, report.action])
362
+ end
363
+
364
+ # The items remaining in the Set are unprocessed resource+actions,
365
+ # so we'll create new resource reports for them which default to
366
+ # a state of "unprocessed".
367
+ collection_resources.each do |resource, action|
368
+ add_resource_report(create_resource_report(resource, action))
369
+ end
370
+ end
371
+
336
372
  # If we are getting messages about a resource while we are in the middle of
337
373
  # another resource's update, we assume that the nested resource is just the
338
374
  # implementation of a provider, and we want to hide it from the reporting