chef 17.6.18 → 17.7.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/chef.gemspec +1 -0
  4. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  5. data/lib/chef/chef_fs/path_utils.rb +1 -1
  6. data/lib/chef/data_collector/run_end_message.rb +1 -1
  7. data/lib/chef/dsl/reboot_pending.rb +1 -1
  8. data/lib/chef/exceptions.rb +10 -0
  9. data/lib/chef/provider/cron.rb +4 -1
  10. data/lib/chef/provider/git.rb +1 -1
  11. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  12. data/lib/chef/provider/subversion.rb +5 -5
  13. data/lib/chef/resource/chocolatey_config.rb +1 -1
  14. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  15. data/lib/chef/resource/chocolatey_source.rb +24 -2
  16. data/lib/chef/resource/directory.rb +1 -1
  17. data/lib/chef/resource/habitat_install.rb +3 -3
  18. data/lib/chef/resource/inspec_waiver.rb +1 -1
  19. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  20. data/lib/chef/resource/kernel_module.rb +27 -2
  21. data/lib/chef/resource/macos_userdefaults.rb +43 -128
  22. data/lib/chef/resource/windows_auto_run.rb +1 -1
  23. data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
  24. data/lib/chef/resource/windows_update_settings.rb +3 -3
  25. data/lib/chef/resource.rb +1 -1
  26. data/lib/chef/resource_reporter.rb +1 -1
  27. data/lib/chef/secret_fetcher/azure_key_vault.rb +62 -8
  28. data/lib/chef/secret_fetcher.rb +0 -1
  29. data/lib/chef/version.rb +1 -1
  30. data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
  31. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  32. data/spec/functional/resource/dsc_script_spec.rb +2 -2
  33. data/spec/functional/resource/macos_userdefaults_spec.rb +119 -0
  34. data/spec/functional/resource/registry_spec.rb +81 -81
  35. data/spec/functional/win32/registry_spec.rb +8 -8
  36. data/spec/unit/data_collector_spec.rb +24 -1
  37. data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
  38. data/spec/unit/mixin/default_paths_spec.rb +1 -1
  39. data/spec/unit/mixin/securable_spec.rb +3 -3
  40. data/spec/unit/provider/cron_spec.rb +45 -0
  41. data/spec/unit/provider/package/rubygems_spec.rb +5 -5
  42. data/spec/unit/provider/package/windows_spec.rb +1 -1
  43. data/spec/unit/provider/registry_key_spec.rb +4 -4
  44. data/spec/unit/provider/service/windows_spec.rb +5 -5
  45. data/spec/unit/provider/subversion_spec.rb +4 -4
  46. data/spec/unit/provider/windows_env_spec.rb +1 -1
  47. data/spec/unit/provider/zypper_repository_spec.rb +1 -1
  48. data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
  49. data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
  50. data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
  51. data/spec/unit/resource/kernel_module_spec.rb +2 -1
  52. data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
  53. data/spec/unit/resource/registry_key_spec.rb +10 -10
  54. data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
  55. data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
  56. data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
  57. data/spec/unit/resource/windows_task_spec.rb +3 -3
  58. data/spec/unit/resource_reporter_spec.rb +2 -2
  59. data/spec/unit/resource_spec.rb +5 -0
  60. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
  61. data/spec/unit/util/backup_spec.rb +1 -1
  62. data/spec/unit/win32/registry_spec.rb +3 -3
  63. metadata +21 -6
@@ -41,7 +41,7 @@ class Chef
41
41
  as_hash["result"] = action_record.action.to_s
42
42
  if new_resource.cookbook_name
43
43
  as_hash["cookbook_name"] = new_resource.cookbook_name
44
- as_hash["cookbook_version"] = new_resource.cookbook_version.version
44
+ as_hash["cookbook_version"] = new_resource.cookbook_version&.version
45
45
  end
46
46
 
47
47
  as_hash
@@ -1,4 +1,6 @@
1
1
  require_relative "base"
2
+ require_relative "../exceptions"
3
+ require "uri" unless defined?(URI)
2
4
 
3
5
  class Chef
4
6
  class SecretFetcher
@@ -14,13 +16,19 @@ class Chef
14
16
  #
15
17
  # @example
16
18
  #
17
- # fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context )
19
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context)
18
20
  # fetcher.fetch("secretkey1", "v1")
19
21
  #
20
22
  # @example
21
23
  #
22
- # fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context )
24
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context)
23
25
  # fetcher.fetch("my_vault/secretkey1", "v1")
26
+ #
27
+ # @example
28
+ #
29
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, { client_id: "540d76b6-7f76-456c-b68b-ccae4dc9d99d" }, run_context)
30
+ # fetcher.fetch("my_vault/secretkey1", "v1")
31
+ #
24
32
  class AzureKeyVault < Base
25
33
 
26
34
  def do_fetch(name, version)
@@ -48,6 +56,12 @@ class Chef
48
56
  end
49
57
  end
50
58
 
59
+ def validate!
60
+ raise Chef::Exceptions::Secret::ConfigurationInvalid, "You may only specify one (these are mutually exclusive): :object_id, :client_id, or :mi_res_id" if [object_id, client_id, mi_res_id].select { |x| !x.nil? }.length > 1
61
+ end
62
+
63
+ private
64
+
51
65
  # Determine the vault name and secret name from the provided name.
52
66
  # If it is not in the provided name in the form "vault_name/secret_name"
53
67
  # it will determine the vault name from `config[:vault]`.
@@ -63,16 +77,56 @@ class Chef
63
77
  end
64
78
  end
65
79
 
80
+ def api_version
81
+ "2018-02-01"
82
+ end
83
+
84
+ def resource
85
+ "https://vault.azure.net"
86
+ end
87
+
88
+ def object_id
89
+ config[:object_id]
90
+ end
91
+
92
+ def client_id
93
+ config[:client_id]
94
+ end
95
+
96
+ def mi_res_id
97
+ config[:mi_res_id]
98
+ end
99
+
100
+ def token_query
101
+ @token_query ||= begin
102
+ p = {}
103
+ p["api-version"] = api_version
104
+ p["resource"] = resource
105
+ p["object_id"] = object_id if object_id
106
+ p["client_id"] = client_id if client_id
107
+ p["mi_res_id"] = mi_res_id if mi_res_id
108
+ URI.encode_www_form(p)
109
+ end
110
+ end
111
+
66
112
  def fetch_token
67
- token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net")
113
+ token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token")
114
+ token_uri.query = token_query
68
115
  http = Net::HTTP.new(token_uri.host, token_uri.port)
69
116
  response = http.get(token_uri, { "Metadata" => "true" })
70
- body = JSON.parse(response.body)
71
- body["access_token"]
117
+
118
+ case response
119
+ when Net::HTTPSuccess
120
+ body = JSON.parse(response.body)
121
+ body["access_token"]
122
+ when Net::HTTPBadRequest
123
+ body = JSON.parse(response.body)
124
+ raise Chef::Exceptions::Secret::Azure::IdentityNotFound if body["error_description"] =~ /identity not found/i
125
+ else
126
+ body = JSON.parse(response.body)
127
+ body["access_token"]
128
+ end
72
129
  end
73
130
  end
74
131
  end
75
132
  end
76
-
77
-
78
-
@@ -58,4 +58,3 @@ class Chef
58
58
  end
59
59
  end
60
60
  end
61
-
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("17.6.18")
26
+ VERSION = Chef::VersionString.new("17.7.22")
27
27
  end
28
28
 
29
29
  #
@@ -39,8 +39,8 @@ describe Chef::DSL::RebootPending, :windows_only do
39
39
  let(:reg_key) { nil }
40
40
  let(:original_set) { false }
41
41
 
42
- describe 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations' do
43
- let(:reg_key) { 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager' }
42
+ describe "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\PendingFileRenameOperations" do
43
+ let(:reg_key) { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager" }
44
44
  let(:original_set) { registry.value_exists?(reg_key, { name: "PendingFileRenameOperations" }) }
45
45
 
46
46
  it "returns true if the registry value exists" do
@@ -78,7 +78,7 @@ describe Chef::DSL::RebootPending, :windows_only do
78
78
 
79
79
  describe "when there is nothing to indicate a reboot is pending" do
80
80
  it "should return false" do
81
- skip "reboot pending" if registry_value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { name: "PendingFileRenameOperations" }) ||
81
+ skip "reboot pending" if registry_value_exists?("HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager", { name: "PendingFileRenameOperations" }) ||
82
82
  registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') ||
83
83
  registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending')
84
84
  expect(recipe.reboot_pending?).to be_falsey
@@ -24,7 +24,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
24
24
  before(:all) do
25
25
  ::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root"
26
26
  ::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\Branch"
27
- ::Win32::Registry::HKEY_CURRENT_USER.open('Software\\Root', Win32::Registry::KEY_ALL_ACCESS) do |reg|
27
+ ::Win32::Registry::HKEY_CURRENT_USER.open("Software\\Root", Win32::Registry::KEY_ALL_ACCESS) do |reg|
28
28
  reg["RootType1", Win32::Registry::REG_SZ] = "fibrous"
29
29
  reg.write("Roots", Win32::Registry::REG_MULTI_SZ, ["strong roots", "healthy tree"])
30
30
  end
@@ -85,7 +85,7 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only, :ruby64_only d
85
85
  let(:dsc_test_resource_base) do
86
86
  Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
87
87
  end
88
- let(:test_registry_key) { 'HKEY_LOCAL_MACHINE\Software\Chef\Spec\Functional\Resource\dsc_script_spec' }
88
+ let(:test_registry_key) { "HKEY_LOCAL_MACHINE\\Software\\Chef\\Spec\\Functional\\Resource\\dsc_script_spec" }
89
89
  let(:test_registry_value) { "Registration" }
90
90
  let(:test_registry_data1) { "LL927" }
91
91
  let(:test_registry_data2) { "LL928" }
@@ -394,7 +394,7 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only, :ruby64_only d
394
394
  dsc_test_run_context.node.consume_external_attrs(OHAI_SYSTEM.data, {})
395
395
  end
396
396
 
397
- let(:configuration_data_path) { 'C:\\configurationdata.psd1' }
397
+ let(:configuration_data_path) { "C:\\configurationdata.psd1" }
398
398
 
399
399
  let(:self_signed_cert_path) do
400
400
  File.join(CHEF_SPEC_DATA, "dsc_lcm.pfx")
@@ -0,0 +1,119 @@
1
+ #
2
+ # Copyright:: Copyright (c) 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
+ require "spec_helper"
18
+
19
+ describe Chef::Resource::MacosUserDefaults, :macos_only, requires_root: true do
20
+ def create_resource
21
+ node = Chef::Node.new
22
+ events = Chef::EventDispatch::Dispatcher.new
23
+ run_context = Chef::RunContext.new(node, {}, events)
24
+ resource = Chef::Resource::MacosUserDefaults.new("test", run_context)
25
+ resource
26
+ end
27
+
28
+ let(:resource) do
29
+ create_resource
30
+ end
31
+
32
+ context "has a default value" do
33
+ it ":macos_userdefaults for resource name" do
34
+ expect(resource.name).to eq("test")
35
+ end
36
+
37
+ it "NSGlobalDomain for the domain property" do
38
+ expect(resource.domain).to eq("NSGlobalDomain")
39
+ end
40
+
41
+ it "nil for the host property" do
42
+ expect(resource.host).to be_nil
43
+ end
44
+
45
+ it "nil for the user property" do
46
+ expect(resource.user).to be_nil
47
+ end
48
+
49
+ it ":write for resource action" do
50
+ expect(resource.action).to eq([:write])
51
+ end
52
+ end
53
+
54
+ it "supports :write, :delete actions" do
55
+ expect { resource.action :write }.not_to raise_error
56
+ expect { resource.action :delete }.not_to raise_error
57
+ end
58
+
59
+ context "can process expected data" do
60
+ it "set array values" do
61
+ resource.domain "/Library/Preferences/ManagedInstalls"
62
+ resource.key "TestArrayValues"
63
+ resource.value [ "/Library/Managed Installs/fake.log", "/Library/Managed Installs/also_fake.log"]
64
+ resource.run_action(:write)
65
+ expect(resource.get_preference resource).to eq([ "/Library/Managed Installs/fake.log", "/Library/Managed Installs/also_fake.log"])
66
+ end
67
+
68
+ it "set dictionary value" do
69
+ resource.domain "/Library/Preferences/ManagedInstalls"
70
+ resource.key "TestDictionaryValues"
71
+ resource.value "User": "/Library/Managed Installs/way_fake.log"
72
+ resource.run_action(:write)
73
+ expect(resource.get_preference resource).to eq("User" => "/Library/Managed Installs/way_fake.log")
74
+ end
75
+
76
+ it "set array of dictionaries" do
77
+ resource.domain "/Library/Preferences/ManagedInstalls"
78
+ resource.key "TestArrayWithDictionary"
79
+ resource.value [ { "User": "/Library/Managed Installs/way_fake.log" } ]
80
+ resource.run_action(:write)
81
+ expect(resource.get_preference resource).to eq([ { "User" => "/Library/Managed Installs/way_fake.log" } ])
82
+ end
83
+
84
+ it "set boolean for preference value" do
85
+ resource.domain "/Library/Preferences/ManagedInstalls"
86
+ resource.key "TestBooleanValue"
87
+ resource.value true
88
+ resource.run_action(:write)
89
+ expect(resource.get_preference resource).to eq(true)
90
+ end
91
+
92
+ it "sets value to global domain when domain is not passed" do
93
+ resource.key "TestKey"
94
+ resource.value 1
95
+ resource.run_action(:write)
96
+ expect(resource.get_preference resource).to eq(1)
97
+ end
98
+
99
+ it "short domain names" do
100
+ resource.domain "com.apple.dock"
101
+ resource.key "titlesize"
102
+ resource.value "20"
103
+ resource.run_action(:write)
104
+ expect(resource.get_preference resource).to eq("20")
105
+ end
106
+ end
107
+
108
+ it "we can delete a preference with full path" do
109
+ resource.domain "/Library/Preferences/ManagedInstalls"
110
+ resource.key "TestKey"
111
+ expect { resource.run_action(:delete) }. to_not raise_error
112
+ end
113
+
114
+ it "we can delete a preference with short name" do
115
+ resource.domain "com.apple.dock"
116
+ resource.key "titlesize"
117
+ expect { resource.run_action(:delete) }. to_not raise_error
118
+ end
119
+ end