chef 17.6.18 → 17.9.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/chef.gemspec +1 -0
  4. data/lib/chef/application/base.rb +1 -1
  5. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  6. data/lib/chef/chef_fs/path_utils.rb +1 -1
  7. data/lib/chef/compliance/default_attributes.rb +12 -2
  8. data/lib/chef/compliance/runner.rb +51 -5
  9. data/lib/chef/data_collector/run_end_message.rb +1 -1
  10. data/lib/chef/dsl/reboot_pending.rb +1 -1
  11. data/lib/chef/exceptions.rb +10 -0
  12. data/lib/chef/mixin/powershell_exec.rb +6 -5
  13. data/lib/chef/mixin/why_run.rb +8 -2
  14. data/lib/chef/powershell.rb +8 -6
  15. data/lib/chef/provider/cron.rb +6 -3
  16. data/lib/chef/provider/directory.rb +2 -2
  17. data/lib/chef/provider/git.rb +1 -1
  18. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  19. data/lib/chef/provider/ifconfig.rb +4 -4
  20. data/lib/chef/provider/mount/linux.rb +16 -2
  21. data/lib/chef/provider/mount/mount.rb +1 -1
  22. data/lib/chef/provider/package/dnf.rb +1 -1
  23. data/lib/chef/provider/package/habitat.rb +1 -1
  24. data/lib/chef/provider/package/powershell.rb +13 -10
  25. data/lib/chef/provider/package/yum/python_helper.rb +81 -25
  26. data/lib/chef/provider/package/yum.rb +39 -12
  27. data/lib/chef/provider/package/zypper.rb +2 -0
  28. data/lib/chef/provider/package.rb +62 -27
  29. data/lib/chef/provider/subversion.rb +5 -5
  30. data/lib/chef/provider.rb +5 -2
  31. data/lib/chef/providers.rb +0 -1
  32. data/lib/chef/pwsh.rb +3 -2
  33. data/lib/chef/resource/apt_package.rb +2 -2
  34. data/lib/chef/resource/chef_client_config.rb +21 -1
  35. data/lib/chef/resource/chef_client_launchd.rb +1 -1
  36. data/lib/chef/resource/chef_client_trusted_certificate.rb +1 -0
  37. data/lib/chef/resource/chocolatey_config.rb +1 -1
  38. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  39. data/lib/chef/resource/chocolatey_package.rb +3 -3
  40. data/lib/chef/resource/chocolatey_source.rb +24 -2
  41. data/lib/chef/resource/cron/cron.rb +75 -1
  42. data/lib/chef/resource/cron/cron_d.rb +2 -1
  43. data/lib/chef/resource/directory.rb +1 -1
  44. data/lib/chef/resource/dnf_package.rb +4 -6
  45. data/lib/chef/resource/dpkg_package.rb +5 -0
  46. data/lib/chef/resource/execute.rb +1 -4
  47. data/lib/chef/resource/habitat_install.rb +5 -5
  48. data/lib/chef/resource/homebrew_tap.rb +0 -4
  49. data/lib/chef/resource/inspec_waiver.rb +1 -1
  50. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  51. data/lib/chef/resource/kernel_module.rb +27 -2
  52. data/lib/chef/resource/launchd.rb +0 -3
  53. data/lib/chef/resource/macos_userdefaults.rb +41 -131
  54. data/lib/chef/resource/powershell_package_source.rb +8 -8
  55. data/lib/chef/resource/rhsm_register.rb +31 -0
  56. data/lib/chef/resource/support/client.erb +7 -0
  57. data/lib/chef/resource/windows_auto_run.rb +1 -1
  58. data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
  59. data/lib/chef/resource/windows_feature_powershell.rb +8 -9
  60. data/lib/chef/resource/windows_task.rb +25 -10
  61. data/lib/chef/resource/windows_update_settings.rb +3 -3
  62. data/lib/chef/resource.rb +2 -2
  63. data/lib/chef/resource_reporter.rb +1 -1
  64. data/lib/chef/secret_fetcher/azure_key_vault.rb +64 -8
  65. data/lib/chef/secret_fetcher/hashi_vault.rb +37 -3
  66. data/lib/chef/secret_fetcher.rb +0 -1
  67. data/lib/chef/version.rb +1 -1
  68. data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
  69. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  70. data/spec/functional/resource/dnf_package_spec.rb +138 -124
  71. data/spec/functional/resource/dpkg_package_spec.rb +16 -0
  72. data/spec/functional/resource/dsc_script_spec.rb +2 -2
  73. data/spec/functional/resource/macos_userdefaults_spec.rb +139 -0
  74. data/spec/functional/resource/registry_spec.rb +81 -81
  75. data/spec/functional/resource/yum_package_spec.rb +789 -129
  76. data/spec/functional/resource/zypper_package_spec.rb +7 -0
  77. data/spec/functional/win32/registry_spec.rb +8 -8
  78. data/spec/integration/client/client_spec.rb +31 -0
  79. data/spec/unit/application/base_spec.rb +40 -0
  80. data/spec/unit/compliance/runner_spec.rb +62 -1
  81. data/spec/unit/data_collector_spec.rb +24 -1
  82. data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
  83. data/spec/unit/file_access_control_spec.rb +1 -1
  84. data/spec/unit/mixin/default_paths_spec.rb +1 -1
  85. data/spec/unit/mixin/securable_spec.rb +3 -3
  86. data/spec/unit/mixin/why_run_spec.rb +53 -0
  87. data/spec/unit/provider/cron_spec.rb +45 -0
  88. data/spec/unit/provider/group/groupadd_spec.rb +1 -0
  89. data/spec/unit/provider/group/usermod_spec.rb +2 -2
  90. data/spec/unit/provider/ifconfig_spec.rb +2 -0
  91. data/spec/unit/provider/mount/linux_spec.rb +16 -3
  92. data/spec/unit/provider/package/bff_spec.rb +1 -0
  93. data/spec/unit/provider/package/powershell_spec.rb +114 -114
  94. data/spec/unit/provider/package/rubygems_spec.rb +8 -5
  95. data/spec/unit/provider/package/solaris_spec.rb +1 -0
  96. data/spec/unit/provider/package/windows_spec.rb +1 -1
  97. data/spec/unit/provider/registry_key_spec.rb +4 -4
  98. data/spec/unit/provider/service/arch_service_spec.rb +2 -2
  99. data/spec/unit/provider/service/debian_service_spec.rb +1 -0
  100. data/spec/unit/provider/service/gentoo_service_spec.rb +1 -0
  101. data/spec/unit/provider/service/macosx_spec.rb +1 -0
  102. data/spec/unit/provider/service/redhat_spec.rb +4 -1
  103. data/spec/unit/provider/service/simple_service_spec.rb +6 -4
  104. data/spec/unit/provider/service/windows_spec.rb +5 -5
  105. data/spec/unit/provider/subversion_spec.rb +4 -4
  106. data/spec/unit/provider/user_spec.rb +2 -0
  107. data/spec/unit/provider/windows_env_spec.rb +1 -1
  108. data/spec/unit/provider/zypper_repository_spec.rb +1 -1
  109. data/spec/unit/resource/chef_client_trusted_certificate_spec.rb +14 -0
  110. data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
  111. data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
  112. data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
  113. data/spec/unit/resource/dpkg_package_spec.rb +12 -0
  114. data/spec/unit/resource/kernel_module_spec.rb +2 -1
  115. data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
  116. data/spec/unit/resource/registry_key_spec.rb +10 -10
  117. data/spec/unit/resource/rhsm_register_spec.rb +42 -0
  118. data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
  119. data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
  120. data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
  121. data/spec/unit/resource/windows_task_spec.rb +3 -3
  122. data/spec/unit/resource_reporter_spec.rb +2 -2
  123. data/spec/unit/resource_spec.rb +5 -0
  124. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
  125. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +46 -0
  126. data/spec/unit/util/backup_spec.rb +1 -1
  127. data/spec/unit/win32/registry_spec.rb +3 -3
  128. metadata +24 -9
  129. data/lib/chef/provider/group/suse.rb +0 -82
  130. data/spec/unit/provider/group/suse_spec.rb +0 -90
@@ -377,7 +377,7 @@ describe Chef::Resource::WindowsFirewallRule do
377
377
  resource.icmp_type("Any")
378
378
  resource.firewall_action(:notconfigured)
379
379
  resource.profile(:domain)
380
- resource.program('%WINDIR%\System32\lsass.exe')
380
+ resource.program("%WINDIR%\\System32\\lsass.exe")
381
381
  resource.service("SomeService")
382
382
  resource.interface_type(:remoteaccess)
383
383
  resource.enabled(false)
@@ -499,7 +499,7 @@ describe Chef::Resource::WindowsFirewallRule do
499
499
  resource.icmp_type("Any")
500
500
  resource.firewall_action(:notconfigured)
501
501
  resource.profile(:domain)
502
- resource.program('%WINDIR%\System32\lsass.exe')
502
+ resource.program("%WINDIR%\\System32\\lsass.exe")
503
503
  resource.service("SomeService")
504
504
  resource.interface_type(:remoteaccess)
505
505
  resource.enabled(false)
@@ -75,7 +75,7 @@ describe Chef::Resource::WindowsTask, :windows_only do
75
75
  context "a System User" do
76
76
  before do
77
77
  resource.frequency :hourly
78
- resource.user 'NT AUTHORITY\SYSTEM'
78
+ resource.user "NT AUTHORITY\\SYSTEM"
79
79
  end
80
80
 
81
81
  context "for an interactive task" do
@@ -88,7 +88,7 @@ describe Chef::Resource::WindowsTask, :windows_only do
88
88
  expect { resource.after_created }.to raise_error(ArgumentError, "Password is not required for system users.")
89
89
  end
90
90
  it "does not raises an error even when user is in lowercase" do
91
- resource.user 'nt authority\system'
91
+ resource.user "nt authority\\system"
92
92
  expect { resource.after_created }.to_not raise_error
93
93
  end
94
94
  end
@@ -103,7 +103,7 @@ describe Chef::Resource::WindowsTask, :windows_only do
103
103
  expect { resource.after_created }.to raise_error(ArgumentError, "Password is not required for system users.")
104
104
  end
105
105
  it "does not raises an error even when user is in lowercase" do
106
- resource.user 'nt authority\system'
106
+ resource.user "nt authority\\system"
107
107
  expect { resource.after_created }.to_not raise_error
108
108
  end
109
109
  end
@@ -494,7 +494,7 @@ describe Chef::ResourceReporter do
494
494
 
495
495
  context "when the resource is a RegistryKey with binary data" do
496
496
  let(:new_resource) do
497
- resource = Chef::Resource::RegistryKey.new('Wubba\Lubba\Dub\Dubs')
497
+ resource = Chef::Resource::RegistryKey.new("Wubba\\Lubba\\Dub\\Dubs")
498
498
  resource.values([ { name: "rick", type: :binary, data: 255.chr * 1 } ])
499
499
  allow(resource).to receive(:cookbook_name).and_return(cookbook_name)
500
500
  allow(resource).to receive(:cookbook_version).and_return(cookbook_version)
@@ -502,7 +502,7 @@ describe Chef::ResourceReporter do
502
502
  end
503
503
 
504
504
  let(:current_resource) do
505
- resource = Chef::Resource::RegistryKey.new('Wubba\Lubba\Dub\Dubs')
505
+ resource = Chef::Resource::RegistryKey.new("Wubba\\Lubba\\Dub\\Dubs")
506
506
  resource.values([ { name: "rick", type: :binary, data: 255.chr * 1 } ])
507
507
  resource
508
508
  end
@@ -348,6 +348,11 @@ describe Chef::Resource do
348
348
  it "should recognize dynamically defined resources" do
349
349
  expect(resource.defined_at).to eq("dynamically defined")
350
350
  end
351
+
352
+ it "should return nil for the cookbook_version when the cookbook_name is @recipe_files" do
353
+ resource.cookbook_name = "@recipe_files"
354
+ expect(resource.cookbook_version).to be nil
355
+ end
351
356
  end
352
357
 
353
358
  describe "to_s" do
@@ -20,51 +20,130 @@
20
20
  require_relative "../../spec_helper"
21
21
  require "chef/secret_fetcher"
22
22
  require "chef/secret_fetcher/azure_key_vault"
23
+ require "net/http/responses"
23
24
 
24
25
  describe Chef::SecretFetcher::AzureKeyVault do
25
- let(:config) { { vault: "my_vault" } }
26
+ let(:config) { { vault: "my-vault" } }
26
27
  let(:fetcher) { Chef::SecretFetcher::AzureKeyVault.new(config, nil) }
28
+ let(:secrets_response_body) { '{ "value" : "my secret value" }' }
29
+ let(:secrets_response_mock) do
30
+ rm = Net::HTTPSuccess.new("1.0", "400", "OK")
31
+ allow(rm).to receive(:body).and_return(secrets_response_body)
32
+ rm
33
+ end
34
+ let(:token_response_body) { %Q({"access_token":"#{access_token}","client_id":"#{client_id}","expires_in":"86294","expires_on":"1627761860","ext_expires_in":"86399","not_before":"1627675160","resource":"https://vault.azure.net","token_type":"Bearer"}) }
35
+ let(:access_token) { "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL3ZhdWx0LmF6dXJlLm5ldCIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2E5ZTY2ZDhkLTA1ZTAtNGMwMC1iOWRkLWM0Yjc3M2U5MWNhNi8iLCJpYXQiOjE2Mjc2NzUxNjAsIm5iZiI6MTYyNzY3NTE2MCwiZXhwIjoxNjI3NzYxODYwLCJhaW8iOiJFMlpnWUhCWGplaTdWS214eEh6bjdoSWpNZFlMQUE9PSIsImFwcGlkIjoiNjU2Mjc1MjEtMzYzYi00ZDk2LTkyMTctMjcIsIm9pZCI6IjNiZjI1NjVhLWY4NWQtNDBiNy1hZWJkLTNlZDA1ZDA0N2FmNiIsInJoIjoiMC5BUk1BalczbXFlQUZBRXk1M2NTM2Mta2NwaUYxWW1VN05wWk5raGNuRGpuZEwxb1RBQUEuIiwic3ViIjoiM2JmMjU2NWEtZjg1ZC00MGI3LWFlYmQtM2VkMDVkMDQ3YWY2IiwidGlkIjoiYTllNjZkOGQtMDVlMC00YzAwLWI5ZGQtYzRiNzczZTkxY2E2IiwidXRpIjoibXlzeHpSRTV3ay1ibTFlYkNqc09BQSIsInZlciI6IjEuMCIsInhtc19taXJpZCI6Ii9zdWJzY3JpcHRpb25zLzYzNDJkZDZkLTc1NTQtNDJjOS04NTM2LTdkZmU3MmY1MWZhZC9yZXNvdXJjZWdyb3Vwcy9pbWFnZS1waXBlbGluZS1ydW5uZXItcWEtZWFzdHVzMi1yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZWRJZGVudGl0eS91c2VyQXNzaWduZWRJZGVudGl0aWVzL2ltYWdlLXBpcGVsaW5lLXJ1bm5lci1xYS1lYXN0dXMyLW1pIn0.BquzjN6d0g4zlvkbkdVwNEfRxIXSmxYwCHMk6UG3iza2fVioiOrcoP4Cp9P5--AB4G_CAhIXaP7YIZs3mq05QiDjSvkVAM0t67UPGhEr66sNXkV72iZBnKca_auh6EHsjPfxeVHkE1wdrsncrYdKhzgO4IAj8Jg4N5qjcE2q-OkliadmEuTwrhPhq" }
36
+ let(:token_response_mock) do
37
+ rm = Net::HTTPSuccess.new("1.0", "400", "OK")
38
+ allow(rm).to receive(:body).and_return(token_response_body)
39
+ rm
40
+ end
41
+ let(:client_id) { SecureRandom.uuid }
42
+ let(:http_mock) { instance_double("Net::HTTP", :use_ssl= => nil) }
43
+ let(:token_uri) { URI.parse("http://169.254.169.254/metadata/identity/oauth2/token") }
44
+ let(:vault_name) { "my-vault" }
45
+ let(:secret_name) { "my-secret" }
46
+ let(:vault_secret_uri) { URI.parse("https://#{vault_name}.vault.azure.net/secrets/#{secret_name}/?api-version=7.2") }
47
+
48
+ before do
49
+ # Cache these up front so we can pass into allow statements without hitting:
50
+ # URI received :parse with unexpected arguments
51
+ token_uri
52
+ vault_secret_uri
53
+ end
54
+
55
+ before do
56
+ allow(Net::HTTP).to receive(:new).and_return(http_mock)
57
+ allow(URI).to receive(:parse).with("http://169.254.169.254/metadata/identity/oauth2/token").and_return(token_uri)
58
+ allow(URI).to receive(:parse).with("https://#{vault_name}.vault.azure.net/secrets/#{secret_name}/?api-version=7.2").and_return(vault_secret_uri)
59
+ allow(http_mock).to receive(:get).with(token_uri, { "Metadata" => "true" }).and_return(token_response_mock)
60
+ allow(http_mock).to receive(:get).with(vault_secret_uri, { "Authorization" => "Bearer #{access_token}", "Content-Type" => "application/json" }).and_return(secrets_response_mock)
61
+ end
62
+
63
+ describe "#validate!" do
64
+ it "raises error when more than one is provided: :object_id, :client_id, :mi_res_id" do
65
+ expect { Chef::SecretFetcher::AzureKeyVault.new({ object_id: "abc", client_id: "abc", mi_res_id: "abc" }, nil).validate! }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
66
+ expect { Chef::SecretFetcher::AzureKeyVault.new({ object_id: "abc", client_id: "abc" }, nil).validate! }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
67
+ expect { Chef::SecretFetcher::AzureKeyVault.new({ object_id: "abc", mi_res_id: "abc" }, nil).validate! }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
68
+ expect { Chef::SecretFetcher::AzureKeyVault.new({ client_id: "abc", mi_res_id: "abc" }, nil).validate! }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
69
+ end
70
+ end
27
71
 
28
- context "when performing a fetch" do
29
- let(:body) { '{ "value" : "my secret value" }' }
30
- let(:response_mock) { double("response", body: body) }
31
- let(:http_mock) { double("http", :get => response_mock, :use_ssl= => nil) }
72
+ describe "#fetch_token" do
73
+ context "when Net::HTTPBadRequest is returned and the error description contains \"Identity not found\"" do
74
+ let(:token_response_mock) { Net::HTTPBadRequest.new("1.0", "400", "Bad Request") }
75
+
76
+ before do
77
+ allow(fetcher).to receive(:fetch_token).and_call_original
78
+ allow(token_response_mock).to receive(:body).and_return('{"error":"invalid_request","error_description":"Identity not found"}')
79
+ end
32
80
 
33
- before do
34
- allow(fetcher).to receive(:fetch_token).and_return "a token"
35
- allow(Net::HTTP).to receive(:new).and_return(http_mock)
81
+ it "raises Chef::Exceptions::Secret::Azure::IdentityNotFound" do
82
+ expect { fetcher.send(:fetch_token) }.to raise_error(Chef::Exceptions::Secret::Azure::IdentityNotFound)
83
+ end
36
84
  end
37
85
 
38
- context "and vault name is only provided in the secret name" do
39
- let(:body) { '{ "value" : "my secret value" }' }
86
+ context "when :object_id is provided" do
87
+ let(:object_id) { SecureRandom.uuid }
88
+ let(:config) { { vault: "my-vault", object_id: object_id } }
89
+
90
+ it "adds client_id to request params" do
91
+ fetcher.send(:fetch_token)
92
+ expect(token_uri.query).to match(/object_id=#{object_id}/)
93
+ end
94
+ end
95
+
96
+ context "when :client_id is provided" do
97
+ let(:config) { { vault: "my-vault", client_id: client_id } }
98
+
99
+ it "adds client_id to request params" do
100
+ fetcher.send(:fetch_token)
101
+ expect(token_uri.query).to match(/client_id=#{client_id}/)
102
+ end
103
+ end
104
+
105
+ context "when :mi_res_id is provided" do
106
+ let(:mi_res_id) { SecureRandom.uuid }
107
+ let(:config) { { vault: "my-vault", mi_res_id: mi_res_id } }
108
+
109
+ it "adds client_id to request params" do
110
+ fetcher.send(:fetch_token)
111
+ expect(token_uri.query).to match(/mi_res_id=#{mi_res_id}/)
112
+ end
113
+ end
114
+ end
115
+
116
+ describe "#fetch" do
117
+ context "when vault name is only provided in the secret name" do
118
+ let(:secrets_response_body) { '{ "value" : "my secret value" }' }
40
119
  let(:config) { {} }
41
120
  it "fetches the value" do
42
- expect(fetcher.fetch("my_vault/value")).to eq "my secret value"
121
+ expect(fetcher.fetch("my-vault/my-secret")).to eq "my secret value"
43
122
  end
44
123
  end
45
124
 
46
- context "and vault name is not provided in the secret name" do
125
+ context "when vault name is not provided in the secret name" do
47
126
  context "and vault name is not provided in config" do
48
127
  let(:config) { {} }
49
128
  it "raises a ConfigurationInvalid exception" do
50
- expect { fetcher.fetch("value") }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
129
+ expect { fetcher.fetch("my-secret") }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
51
130
  end
52
131
  end
53
132
 
54
133
  context "and vault name is provided in config" do
55
- let(:config) { { vault: "my_vault" } }
134
+ let(:config) { { vault: "my-vault" } }
56
135
  it "fetches the value" do
57
- expect(fetcher.fetch("value")).to eq "my secret value"
136
+ expect(fetcher.fetch("my-secret")).to eq "my secret value"
58
137
  end
59
138
  end
60
139
  end
61
- context "and an error response is received in the body" do
62
- let(:config) { { vault: "my_vault" } }
63
- let(:body) { '{ "error" : { "code" : 404, "message" : "secret not found" } }' }
140
+
141
+ context "when an error response is received in the response body" do
142
+ let(:config) { { vault: "my-vault" } }
143
+ let(:secrets_response_body) { '{ "error" : { "code" : 404, "message" : "secret not found" } }' }
64
144
  it "raises FetchFailed" do
65
- expect { fetcher.fetch("value") }.to raise_error(Chef::Exceptions::Secret::FetchFailed)
145
+ expect { fetcher.fetch("my-secret") }.to raise_error(Chef::Exceptions::Secret::FetchFailed)
66
146
  end
67
147
  end
68
148
  end
69
149
  end
70
-
@@ -65,6 +65,52 @@ describe Chef::SecretFetcher::HashiVault do
65
65
  fetcher.validate!
66
66
  end
67
67
  end
68
+
69
+ context "and using auth_method: :approle" do
70
+ it "raises ConfigurationInvalid message when :approle_name or :approle_id are not specified" do
71
+ fetcher = Chef::SecretFetcher::HashiVault.new( { auth_method: :approle, vault_addr: "https://vault.example.com:8200" }, run_context)
72
+ expect { fetcher.validate! }.to raise_error(Chef::Exceptions::Secret::ConfigurationInvalid)
73
+ end
74
+
75
+ it "authenticates using the approle_id and approle_secret_id during validation when all configuration is correct" do
76
+ fetcher = Chef::SecretFetcher::HashiVault.new({
77
+ auth_method: :approle,
78
+ approle_id: "idguid",
79
+ approle_secret_id: "secretguid",
80
+ vault_addr: "https://vault.example.com:8200" },
81
+ run_context)
82
+ auth = instance_double(Vault::Authenticate)
83
+ allow(auth).to receive(:approle)
84
+ allow(Vault).to receive(:auth).and_return(auth)
85
+ expect(auth).to receive(:approle).with("idguid", "secretguid")
86
+ fetcher.validate!
87
+ end
88
+
89
+ it "looks up the :role_id and :secret_id when all configuration is correct" do
90
+ fetcher = Chef::SecretFetcher::HashiVault.new({
91
+ auth_method: :approle,
92
+ approle_name: "myapprole",
93
+ token: "t.1234abcd",
94
+ vault_addr: "https://vault.example.com:8200" },
95
+ run_context)
96
+ approle = instance_double(Vault::AppRole)
97
+ auth = instance_double(Vault::Authenticate)
98
+ allow(Vault).to receive(:approle).and_return(approle)
99
+ allow(approle).to receive(:role_id).with("myapprole").and_return("idguid")
100
+ allow(approle).to receive(:create_secret_id).with("myapprole").and_return(Vault::Secret.new({
101
+ data: {
102
+ secret_id: "secretguid",
103
+ secret_id_accessor: "accessor_guid",
104
+ secret_id_ttl: 0,
105
+ },
106
+ lease_duration: 0,
107
+ lease_id: "",
108
+ }))
109
+ allow(Vault).to receive(:auth).and_return(auth)
110
+ expect(auth).to receive(:approle).with("idguid", "secretguid")
111
+ fetcher.validate!
112
+ end
113
+ end
68
114
  end
69
115
 
70
116
  context "when fetching a secret from Hashi Vault" do
@@ -132,7 +132,7 @@ describe Chef::Util::Backup do
132
132
  end
133
133
 
134
134
  it "uses the configured Chef::Config[:file_backup_path] and strips the drive on windows" do
135
- expect(@backup).to receive(:path).and_return('c:\\a\\b\\c.txt')
135
+ expect(@backup).to receive(:path).and_return("c:\\a\\b\\c.txt")
136
136
  Chef::Config[:file_backup_path] = 'c:\backupdir'
137
137
  expect(@backup.send(:backup_path)).to match(%r|^c:\\backupdir[\\/]+a\\b\\c.txt.chef-\d{14}.\d{6}$|)
138
138
  end
@@ -23,12 +23,12 @@ describe Chef::Win32::Registry do
23
23
 
24
24
  let(:value1) { { name: "one", type: :string, data: "1" } }
25
25
  let(:value1_upcase_name) { { name: "ONE", type: :string, data: "1" } }
26
- let(:key_path) { 'HKCU\Software\OpscodeNumbers' }
27
- let(:key) { 'Software\OpscodeNumbers' }
26
+ let(:key_path) { "HKCU\\Software\\OpscodeNumbers" }
27
+ let(:key) { "Software\\OpscodeNumbers" }
28
28
  let(:key_parent) { "Software" }
29
29
  let(:key_to_delete) { "OpscodeNumbers" }
30
30
  let(:sub_key) { "OpscodePrimes" }
31
- let(:missing_key_path) { 'HKCU\Software' }
31
+ let(:missing_key_path) { "HKCU\\Software" }
32
32
  let(:registry) { Chef::Win32::Registry.new }
33
33
  let(:hive_mock) { double("::Win32::Registry::HKEY_CURRENT_USER") }
34
34
  let(:reg_mock) { double("reg") }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 17.6.18
4
+ version: 17.9.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-01 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-config
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 17.6.18
19
+ version: 17.9.18
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 17.6.18
26
+ version: 17.9.18
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: chef-utils
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 17.6.18
33
+ version: 17.9.18
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 17.6.18
40
+ version: 17.9.18
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: train-core
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -426,6 +426,20 @@ dependencies:
426
426
  - - "<"
427
427
  - !ruby/object:Gem::Version
428
428
  version: '3.0'
429
+ - !ruby/object:Gem::Dependency
430
+ name: corefoundation
431
+ requirement: !ruby/object:Gem::Requirement
432
+ requirements:
433
+ - - "~>"
434
+ - !ruby/object:Gem::Version
435
+ version: 0.3.4
436
+ type: :runtime
437
+ prerelease: false
438
+ version_requirements: !ruby/object:Gem::Requirement
439
+ requirements:
440
+ - - "~>"
441
+ - !ruby/object:Gem::Version
442
+ version: 0.3.4
429
443
  - !ruby/object:Gem::Dependency
430
444
  name: proxifier
431
445
  requirement: !ruby/object:Gem::Requirement
@@ -855,7 +869,6 @@ files:
855
869
  - lib/chef/provider/group/groupmod.rb
856
870
  - lib/chef/provider/group/pw.rb
857
871
  - lib/chef/provider/group/solaris.rb
858
- - lib/chef/provider/group/suse.rb
859
872
  - lib/chef/provider/group/usermod.rb
860
873
  - lib/chef/provider/group/windows.rb
861
874
  - lib/chef/provider/http_request.rb
@@ -1729,6 +1742,7 @@ files:
1729
1742
  - spec/functional/resource/launchd_spec.rb
1730
1743
  - spec/functional/resource/link_spec.rb
1731
1744
  - spec/functional/resource/locale_spec.rb
1745
+ - spec/functional/resource/macos_userdefaults_spec.rb
1732
1746
  - spec/functional/resource/mount_spec.rb
1733
1747
  - spec/functional/resource/msu_package_spec.rb
1734
1748
  - spec/functional/resource/ohai_spec.rb
@@ -1852,6 +1866,7 @@ files:
1852
1866
  - spec/unit/api_client_v1_spec.rb
1853
1867
  - spec/unit/application/agent_spec.rb
1854
1868
  - spec/unit/application/apply_spec.rb
1869
+ - spec/unit/application/base_spec.rb
1855
1870
  - spec/unit/application/client_spec.rb
1856
1871
  - spec/unit/application/exit_code_spec.rb
1857
1872
  - spec/unit/application/server_spec.rb
@@ -1985,6 +2000,7 @@ files:
1985
2000
  - spec/unit/mixin/user_context_spec.rb
1986
2001
  - spec/unit/mixin/versioned_api_spec.rb
1987
2002
  - spec/unit/mixin/which.rb
2003
+ - spec/unit/mixin/why_run_spec.rb
1988
2004
  - spec/unit/mixin/windows_architecture_helper_spec.rb
1989
2005
  - spec/unit/mixin/xml_escape_spec.rb
1990
2006
  - spec/unit/monologger_spec.rb
@@ -2024,7 +2040,6 @@ files:
2024
2040
  - spec/unit/provider/group/groupmod_spec.rb
2025
2041
  - spec/unit/provider/group/pw_spec.rb
2026
2042
  - spec/unit/provider/group/solaris_spec.rb
2027
- - spec/unit/provider/group/suse_spec.rb
2028
2043
  - spec/unit/provider/group/usermod_spec.rb
2029
2044
  - spec/unit/provider/group/windows_spec.rb
2030
2045
  - spec/unit/provider/group_spec.rb
@@ -2373,7 +2388,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2373
2388
  - !ruby/object:Gem::Version
2374
2389
  version: '0'
2375
2390
  requirements: []
2376
- rubygems_version: 3.2.22
2391
+ rubygems_version: 3.2.32
2377
2392
  signing_key:
2378
2393
  specification_version: 4
2379
2394
  summary: A systems integration framework, built to bring the benefits of configuration
@@ -1,82 +0,0 @@
1
- #
2
- # Author:: AJ Christensen (<aj@chef.io>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "groupadd"
20
- require "etc" unless defined?(Etc)
21
-
22
- class Chef
23
- class Provider
24
- class Group
25
- class Suse < Chef::Provider::Group::Groupadd
26
- provides :group, platform: "suse", platform_version: "< 12.0"
27
-
28
- def load_current_resource
29
- super
30
- end
31
-
32
- def define_resource_requirements
33
- super
34
- requirements.assert(:all_actions) do |a|
35
- a.assertion { ::File.exist?("/usr/sbin/groupmod") }
36
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{new_resource.name}"
37
- # No whyrun alternative: this component should be available in the base install of any given system that uses it
38
- end
39
-
40
- requirements.assert(:create, :manage, :modify) do |a|
41
- a.assertion do
42
-
43
- to_add(new_resource.members).all? { |member| Etc.getpwnam(member) }
44
- rescue
45
- false
46
-
47
- end
48
- a.failure_message Chef::Exceptions::Group, "Could not add users #{to_add(new_resource.members).join(", ")} to #{new_resource.group_name}: one of these users does not exist"
49
- a.whyrun "Could not find one of these users: #{to_add(new_resource.members).join(", ")}. Assuming it will be created by a prior step"
50
- end
51
- end
52
-
53
- def set_members(members)
54
- to_remove(members).each do |member|
55
- remove_member(member)
56
- end
57
-
58
- to_add(members).each do |member|
59
- add_member(member)
60
- end
61
- end
62
-
63
- def to_add(members)
64
- members - current_resource.members
65
- end
66
-
67
- def add_member(member)
68
- shell_out!("groupmod", "-A", member, new_resource.group_name)
69
- end
70
-
71
- def to_remove(members)
72
- current_resource.members - members
73
- end
74
-
75
- def remove_member(member)
76
- shell_out!("groupmod", "-R", member, new_resource.group_name)
77
- end
78
-
79
- end
80
- end
81
- end
82
- end
@@ -1,90 +0,0 @@
1
- #
2
- # Author:: Tom Duffield (<tom@chef.io>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- #      http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require "spec_helper"
20
-
21
- describe Chef::Provider::Group::Suse do
22
- let(:node) { Chef::Node.new }
23
- let(:events) { Chef::EventDispatch::Dispatcher.new }
24
- let(:run_context) { Chef::RunContext.new(node, {}, events) }
25
- let(:new_members) { %w{root new_user} }
26
- let(:new_resource) do
27
- Chef::Resource::Group.new("new_group").tap do |r|
28
- r.gid 50
29
- r.members new_members
30
- r.system false
31
- r.non_unique false
32
- end
33
- end
34
- let(:current_resource) do
35
- Chef::Resource::Group.new("new_group").tap do |r|
36
- r.gid 50
37
- r.members %w{root}
38
- r.system false
39
- r.non_unique false
40
- end
41
- end
42
- let(:provider) do
43
- described_class.new(new_resource, run_context).tap do |p|
44
- p.current_resource = current_resource
45
- end
46
- end
47
-
48
- describe "when determining the current group state" do
49
- before(:each) do
50
- allow(File).to receive(:exist?).and_return(true)
51
- provider.action = :create
52
- provider.define_resource_requirements
53
- end
54
-
55
- # Checking for required binaries is already done in the spec
56
- # for Chef::Provider::Group - no need to repeat it here. We'll
57
- # include only what's specific to this provider.
58
- it "should raise an error if the required binary /usr/sbin/groupmod doesn't exist" do
59
- expect(File).to receive(:exist?).with("/usr/sbin/groupmod").and_return(false)
60
- expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
61
- end
62
-
63
- it "should raise error if one of the member users does not exist" do
64
- expect(Etc).to receive(:getpwnam).with("new_user").and_raise ArgumentError
65
- expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
66
- end
67
- end
68
-
69
- describe "#set_members" do
70
- it "should add missing members and remove deleted members" do
71
- expect(provider).not_to receive(:remove_member)
72
- expect(provider).to receive(:add_member).with("new_user")
73
- provider.set_members(new_members)
74
- end
75
- end
76
-
77
- describe "#add_member" do
78
- it "should call out to groupmod to add user" do
79
- expect(provider).to receive(:shell_out_compacted!).with("groupmod", "-A", "new_user", "new_group")
80
- provider.add_member("new_user")
81
- end
82
- end
83
-
84
- describe "#remove_member" do
85
- it "should call out to groupmod to remove user" do
86
- expect(provider).to receive(:shell_out_compacted!).with("groupmod", "-R", "new_user", "new_group")
87
- provider.remove_member("new_user")
88
- end
89
- end
90
- end