chef 17.3.48-universal-mingw32 → 17.6.15-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/chef.gemspec +2 -0
  4. data/lib/chef/application/base.rb +11 -1
  5. data/lib/chef/application.rb +3 -1
  6. data/lib/chef/client.rb +1 -2
  7. data/lib/chef/compliance/default_attributes.rb +5 -3
  8. data/lib/chef/compliance/input.rb +115 -0
  9. data/lib/chef/compliance/input_collection.rb +139 -0
  10. data/lib/chef/compliance/profile.rb +122 -0
  11. data/lib/chef/compliance/profile_collection.rb +109 -0
  12. data/lib/chef/compliance/reporter/automate.rb +1 -1
  13. data/lib/chef/compliance/runner.rb +62 -6
  14. data/lib/chef/compliance/waiver.rb +115 -0
  15. data/lib/chef/compliance/waiver_collection.rb +143 -0
  16. data/lib/chef/dsl/compliance.rb +38 -0
  17. data/lib/chef/dsl/reader_helpers.rb +51 -0
  18. data/lib/chef/dsl/recipe.rb +4 -2
  19. data/lib/chef/dsl/secret.rb +5 -7
  20. data/lib/chef/dsl/universal.rb +2 -0
  21. data/lib/chef/event_dispatch/base.rb +44 -2
  22. data/lib/chef/exceptions.rb +0 -2
  23. data/lib/chef/formatters/doc.rb +60 -13
  24. data/lib/chef/formatters/error_mapper.rb +2 -2
  25. data/lib/chef/formatters/minimal.rb +6 -5
  26. data/lib/chef/http/basic_client.rb +15 -7
  27. data/lib/chef/http.rb +12 -8
  28. data/lib/chef/provider/execute.rb +1 -1
  29. data/lib/chef/provider/file.rb +2 -0
  30. data/lib/chef/provider/group/dscl.rb +1 -1
  31. data/lib/chef/provider/launchd.rb +6 -6
  32. data/lib/chef/provider/link.rb +2 -2
  33. data/lib/chef/provider/registry_key.rb +3 -2
  34. data/lib/chef/provider/remote_file/http.rb +1 -1
  35. data/lib/chef/provider/subversion.rb +4 -4
  36. data/lib/chef/provider/support/yum_repo.erb +1 -1
  37. data/lib/chef/provider/systemd_unit.rb +17 -16
  38. data/lib/chef/provider/template.rb +1 -1
  39. data/lib/chef/provider/user/mac.rb +3 -3
  40. data/lib/chef/provider/yum_repository.rb +27 -43
  41. data/lib/chef/provider/zypper_repository.rb +3 -3
  42. data/lib/chef/provider.rb +26 -1
  43. data/lib/chef/provider_resolver.rb +8 -2
  44. data/lib/chef/resource/archive_file.rb +17 -14
  45. data/lib/chef/resource/chef_client_scheduled_task.rb +45 -2
  46. data/lib/chef/resource/chocolatey_config.rb +13 -13
  47. data/lib/chef/resource/execute.rb +2 -2
  48. data/lib/chef/resource/file/verification/json.rb +50 -0
  49. data/lib/chef/resource/file/verification/yaml.rb +52 -0
  50. data/lib/chef/resource/homebrew_cask.rb +1 -1
  51. data/lib/chef/resource/inspec_input.rb +127 -0
  52. data/lib/chef/resource/inspec_waiver.rb +184 -0
  53. data/lib/chef/resource/inspec_waiver_file_entry.rb +2 -2
  54. data/lib/chef/resource/launchd.rb +3 -3
  55. data/lib/chef/resource/mount.rb +1 -1
  56. data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
  57. data/lib/chef/resource/powershell_package_source.rb +234 -70
  58. data/lib/chef/resource/registry_key.rb +36 -48
  59. data/lib/chef/resource/remote_file.rb +99 -3
  60. data/lib/chef/resource/rhsm_subscription.rb +5 -5
  61. data/lib/chef/resource/ruby_block.rb +100 -0
  62. data/lib/chef/resource/scm/subversion.rb +1 -1
  63. data/lib/chef/resource/sysctl.rb +2 -2
  64. data/lib/chef/resource/systemd_unit.rb +3 -3
  65. data/lib/chef/resource/timezone.rb +2 -2
  66. data/lib/chef/resource/user_ulimit.rb +1 -0
  67. data/lib/chef/resource/windows_printer.rb +1 -1
  68. data/lib/chef/resource/windows_uac.rb +3 -1
  69. data/lib/chef/resource/windows_user_privilege.rb +1 -1
  70. data/lib/chef/resource/yum_package.rb +1 -5
  71. data/lib/chef/resource.rb +13 -17
  72. data/lib/chef/resource_inspector.rb +6 -2
  73. data/lib/chef/resources.rb +2 -0
  74. data/lib/chef/run_context/cookbook_compiler.rb +112 -28
  75. data/lib/chef/run_context.rb +31 -1
  76. data/lib/chef/secret_fetcher/akeyless_vault.rb +57 -0
  77. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +17 -5
  78. data/lib/chef/secret_fetcher/azure_key_vault.rb +32 -10
  79. data/lib/chef/secret_fetcher/base.rb +6 -2
  80. data/lib/chef/secret_fetcher/hashi_vault.rb +100 -0
  81. data/lib/chef/secret_fetcher.rb +13 -6
  82. data/lib/chef/version.rb +1 -1
  83. data/lib/chef/win32/version.rb +2 -1
  84. data/spec/data/archive_file/test_archive.tar.gz +0 -0
  85. data/spec/functional/resource/archive_file_spec.rb +87 -0
  86. data/spec/functional/resource/group_spec.rb +5 -1
  87. data/spec/functional/resource/link_spec.rb +8 -0
  88. data/spec/functional/resource/powershell_package_source_spec.rb +5 -6
  89. data/spec/integration/compliance/compliance_spec.rb +61 -0
  90. data/spec/integration/recipes/resource_action_spec.rb +2 -2
  91. data/spec/spec_helper.rb +3 -0
  92. data/spec/support/platform_helpers.rb +4 -0
  93. data/spec/support/ruby_installer.rb +51 -0
  94. data/spec/unit/compliance/input_spec.rb +104 -0
  95. data/spec/unit/compliance/profile_spec.rb +120 -0
  96. data/spec/unit/compliance/runner_spec.rb +46 -2
  97. data/spec/unit/compliance/waiver_spec.rb +104 -0
  98. data/spec/unit/dsl/secret_spec.rb +8 -2
  99. data/spec/unit/formatters/doc_spec.rb +1 -1
  100. data/spec/unit/http/basic_client_spec.rb +30 -0
  101. data/spec/unit/http_spec.rb +8 -2
  102. data/spec/unit/provider/link_spec.rb +13 -7
  103. data/spec/unit/provider/remote_file/http_spec.rb +10 -0
  104. data/spec/unit/provider/template_spec.rb +2 -2
  105. data/spec/unit/provider_spec.rb +23 -0
  106. data/spec/unit/resource/archive_file_spec.rb +414 -3
  107. data/spec/unit/resource/chef_client_scheduled_task_spec.rb +69 -0
  108. data/spec/unit/resource/file/verification/json_spec.rb +72 -0
  109. data/spec/unit/resource/file/verification/yaml_spec.rb +67 -0
  110. data/spec/unit/resource/homebrew_cask_spec.rb +29 -11
  111. data/spec/unit/resource/inspec_input_spec.rb +300 -0
  112. data/spec/unit/resource/inspec_waiver_spec.rb +312 -0
  113. data/spec/unit/resource/mount_spec.rb +10 -0
  114. data/spec/unit/resource/powershell_package_source_spec.rb +63 -62
  115. data/spec/unit/resource/rhsm_subscription_spec.rb +50 -3
  116. data/spec/unit/resource/systemd_unit_spec.rb +1 -1
  117. data/spec/unit/resource/user_ulimit_spec.rb +14 -1
  118. data/spec/unit/resource_spec.rb +19 -8
  119. data/spec/unit/secret_fetcher/akeyless_vault_spec.rb +37 -0
  120. data/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb +70 -0
  121. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +23 -16
  122. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +80 -0
  123. data/spec/unit/secret_fetcher_spec.rb +9 -9
  124. data/tasks/rspec.rb +2 -1
  125. metadata +61 -6
@@ -21,7 +21,7 @@ require_relative "exceptions"
21
21
  class Chef
22
22
  class SecretFetcher
23
23
 
24
- SECRET_FETCHERS = %i{example aws_secrets_manager azure_key_vault}.freeze
24
+ SECRET_FETCHERS = %i{example aws_secrets_manager azure_key_vault hashi_vault akeyless_vault}.freeze
25
25
 
26
26
  # Returns a configured and validated instance
27
27
  # of a [Chef::SecretFetcher::Base] for the given
@@ -30,21 +30,28 @@ class Chef
30
30
  # @param service [Symbol] the identifier for the service that will support this request. Must be in
31
31
  # SECRET_FETCHERS
32
32
  # @param config [Hash] configuration that the secrets service requires
33
- def self.for_service(service, config)
33
+ # @param run_context [Chef::RunContext] the run context this is being invoked from
34
+ def self.for_service(service, config, run_context)
34
35
  fetcher = case service
35
36
  when :example
36
37
  require_relative "secret_fetcher/example"
37
- Chef::SecretFetcher::Example.new(config)
38
+ Chef::SecretFetcher::Example.new(config, run_context)
38
39
  when :aws_secrets_manager
39
40
  require_relative "secret_fetcher/aws_secrets_manager"
40
- Chef::SecretFetcher::AWSSecretsManager.new(config)
41
+ Chef::SecretFetcher::AWSSecretsManager.new(config, run_context)
41
42
  when :azure_key_vault
42
43
  require_relative "secret_fetcher/azure_key_vault"
43
- Chef::SecretFetcher::AzureKeyVault.new(config)
44
+ Chef::SecretFetcher::AzureKeyVault.new(config, run_context)
45
+ when :hashi_vault
46
+ require_relative "secret_fetcher/hashi_vault"
47
+ Chef::SecretFetcher::HashiVault.new(config, run_context)
48
+ when :akeyless_vault
49
+ require_relative "secret_fetcher/akeyless_vault"
50
+ Chef::SecretFetcher::AKeylessVault.new(config, run_context)
44
51
  when nil, ""
45
52
  raise Chef::Exceptions::Secret::MissingFetcher.new(SECRET_FETCHERS)
46
53
  else
47
- raise Chef::Exceptions::Secret::InvalidFetcherService.new("Unsupported secret service: #{service}", SECRET_FETCHERS)
54
+ raise Chef::Exceptions::Secret::InvalidFetcherService.new("Unsupported secret service: '#{service}'", SECRET_FETCHERS)
48
55
  end
49
56
  fetcher.validate!
50
57
  fetcher
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.3.48")
26
+ VERSION = Chef::VersionString.new("17.6.15")
27
27
  end
28
28
 
29
29
  #
@@ -49,7 +49,8 @@ class Chef
49
49
  private_class_method :method_name_from_marketing_name
50
50
 
51
51
  WIN_VERSIONS = {
52
- "Windows Server 2019" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 17763 } },
52
+ "Windows Server 2022" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 20348 } },
53
+ "Windows Server 2019" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 17763 && build_number < 20348 } },
53
54
  "Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } },
54
55
  "Windows Server 2016" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number <= 14393 } },
55
56
  "Windows 8.1" => { major: 6, minor: 3, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } },
@@ -0,0 +1,87 @@
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
+
18
+ require "spec_helper"
19
+ require "tmpdir"
20
+
21
+ # Exclude this test on platforms where ffi-libarchive loading is broken
22
+ describe Chef::Resource::ArchiveFile, :libarchive_loading_broken do
23
+ include RecipeDSLHelper
24
+
25
+ let(:tmp_path) { Dir.mktmpdir }
26
+ let(:extract_destination) { "#{tmp_path}/extract_here" }
27
+ let(:test_archive_path) { File.expand_path("archive_file/test_archive.tar.gz", CHEF_SPEC_DATA) }
28
+
29
+ after do
30
+ FileUtils.remove_entry_secure(extract_destination) if File.exist?(extract_destination)
31
+ end
32
+
33
+ context "when strip_components is 0" do
34
+ it "extracts archive to destination" do
35
+ af = archive_file test_archive_path do
36
+ destination extract_destination
37
+ end
38
+ af.should_be_updated
39
+
40
+ expect(af.strip_components).to eq(0) # Validate defaults haven't changed here
41
+ expect(Dir.glob("#{extract_destination}/**/*").length).to eq(4)
42
+ expect(Dir.exist?("#{extract_destination}/folder-1")).to eq(true)
43
+ expect(File.exist?("#{extract_destination}/folder-1/file-1.txt")).to eq(true)
44
+ expect(Dir.exist?("#{extract_destination}/folder-1/folder-2")).to eq(true)
45
+ expect(File.exist?("#{extract_destination}/folder-1/folder-2/file-2.txt")).to eq(true)
46
+ end
47
+ end
48
+
49
+ context "when strip_components is 1" do
50
+ it "extracts archive to destination, with 1 component stripped" do
51
+ archive_file test_archive_path do
52
+ destination extract_destination
53
+ strip_components 1
54
+ end.should_be_updated
55
+
56
+ expect(Dir.exist?("#{extract_destination}/folder-1")).to eq(false)
57
+ expect(File.exist?("#{extract_destination}/folder-1/file-1.txt")).to eq(false)
58
+ expect(Dir.exist?("#{extract_destination}/folder-1/folder-2")).to eq(false)
59
+ expect(File.exist?("#{extract_destination}/folder-1/folder-2/file-2.txt")).to eq(false)
60
+
61
+ expect(Dir.glob("#{extract_destination}/**/*").length).to eq(3)
62
+ expect(File.exist?("#{extract_destination}/file-1.txt")).to eq(true)
63
+ expect(Dir.exist?("#{extract_destination}/folder-2")).to eq(true)
64
+ expect(File.exist?("#{extract_destination}/folder-2/file-2.txt")).to eq(true)
65
+ end
66
+ end
67
+
68
+ context "when strip_components is 2" do
69
+ it "extracts archive to destination, with 2 components stripped" do
70
+ archive_file test_archive_path do
71
+ destination extract_destination
72
+ strip_components 2
73
+ end.should_be_updated
74
+
75
+ expect(Dir.exist?("#{extract_destination}/folder-1")).to eq(false)
76
+ expect(File.exist?("#{extract_destination}/folder-1/file-1.txt")).to eq(false)
77
+ expect(Dir.exist?("#{extract_destination}/folder-1/folder-2")).to eq(false)
78
+ expect(File.exist?("#{extract_destination}/folder-1/folder-2/file-2.txt")).to eq(false)
79
+ expect(File.exist?("#{extract_destination}/file-1.txt")).to eq(false)
80
+ expect(Dir.exist?("#{extract_destination}/folder-2")).to eq(false)
81
+ expect(File.exist?("#{extract_destination}/folder-2/file-2.txt")).to eq(false)
82
+
83
+ expect(Dir.glob("#{extract_destination}/**/*").length).to eq(1)
84
+ expect(File.exist?("#{extract_destination}/file-2.txt")).to eq(true)
85
+ end
86
+ end
87
+ end
@@ -44,6 +44,10 @@ describe Chef::Resource::Group, :requires_root_or_running_windows do
44
44
  members.shift # Get rid of GroupMembership: string
45
45
  members.include?(user)
46
46
  else
47
+ # TODO For some reason our temporary AIX 7.2 system does not correctly report group membership immediately after changes have been made.
48
+ # Adding a 2 second delay for this platform is enough to get correct results.
49
+ # We hope to remove this delay after we get more permanent AIX 7.2 systems in our CI pipeline. reference: https://github.com/chef/release-engineering/issues/1617
50
+ sleep 2 if aix? && (ohai[:platform_version] == "7.2")
47
51
  Etc.getgrnam(group_name).mem.include?(user)
48
52
  end
49
53
  end
@@ -181,7 +185,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows do
181
185
 
182
186
  describe "when the users exist" do
183
187
  before do
184
- high_uid = 30000
188
+ high_uid = 40000
185
189
  (spec_members).each do |member|
186
190
  remove_user(member)
187
191
  create_user(member, high_uid)
@@ -345,9 +345,17 @@ describe Chef::Resource::Link do
345
345
  let(:test_user) { "test-link-user" }
346
346
  before do
347
347
  user(test_user).run_action(:create)
348
+ # TODO For some reason our temporary AIX 7.2 system does not correctly report user existence immediately after changes have been made.
349
+ # Adding a 2 second delay for this platform is enough to get correct results.
350
+ # We hope to remove this delay after we get more permanent AIX 7.2 systems in our CI pipeline. reference: https://github.com/chef/release-engineering/issues/1617
351
+ sleep 2 if aix? && (ohai[:platform_version] == "7.2")
348
352
  end
349
353
  after do
350
354
  user(test_user).run_action(:remove)
355
+ # TODO For some reason our temporary AIX 7.2 system does not correctly report user existence immediately after changes have been made.
356
+ # Adding a 2 second delay for this platform is enough to get correct results.
357
+ # We hope to remove this delay after we get more permanent AIX 7.2 systems in our CI pipeline. reference: https://github.com/chef/release-engineering/issues/1617
358
+ sleep 2 if aix? && (ohai[:platform_version] == "7.2")
351
359
  end
352
360
  before(:each) do
353
361
  resource.owner(test_user)
@@ -22,7 +22,7 @@ describe Chef::Resource::PowershellPackageSource, :windows_gte_10 do
22
22
  include Chef::Mixin::PowershellExec
23
23
 
24
24
  let(:source_name) { "fake" }
25
- let(:url) { "https://www.nuget.org/api/v2" }
25
+ let(:source_location) { "https://www.nuget.org/api/v2" }
26
26
  let(:trusted) { true }
27
27
 
28
28
  let(:run_context) do
@@ -32,7 +32,7 @@ describe Chef::Resource::PowershellPackageSource, :windows_gte_10 do
32
32
  subject do
33
33
  new_resource = Chef::Resource::PowershellPackageSource.new("test powershell package source", run_context)
34
34
  new_resource.source_name source_name
35
- new_resource.url url
35
+ new_resource.source_location source_location
36
36
  new_resource.trusted trusted
37
37
  new_resource.provider_name provider_name
38
38
  new_resource
@@ -61,7 +61,7 @@ describe Chef::Resource::PowershellPackageSource, :windows_gte_10 do
61
61
  it "updates an existing package source if changed" do
62
62
  subject.run_action(:register)
63
63
  subject.trusted !trusted
64
- subject.run_action(:register)
64
+ subject.run_action(:set)
65
65
  expect(subject).to be_updated_by_last_action
66
66
  end
67
67
  end
@@ -73,9 +73,8 @@ describe Chef::Resource::PowershellPackageSource, :windows_gte_10 do
73
73
  expect(get_installed_package_source_name).to be_empty
74
74
  end
75
75
 
76
- it "does not unregister the package source if not already installed" do
77
- subject.run_action(:unregister)
78
- expect(subject).not_to be_updated_by_last_action
76
+ it "does not unregister the package source if not installed" do
77
+ expect { subject.run_action(:unregister) }.to_not raise_error
79
78
  end
80
79
  end
81
80
  end
@@ -47,6 +47,7 @@ describe "chef-client with compliance phase" do
47
47
  {
48
48
  "audit": {
49
49
  "compliance_phase": true,
50
+ "reporter": "json-file",
50
51
  "json_file": {
51
52
  "location": "#{report_file}"
52
53
  },
@@ -79,4 +80,64 @@ describe "chef-client with compliance phase" do
79
80
  expect(result["status"]).to eq("passed")
80
81
  end
81
82
  end
83
+
84
+ when_the_repository "has a compliance segment" do
85
+ let(:report_file) { path_to("report_file.json") }
86
+
87
+ before do
88
+ directory "cookbooks/x" do
89
+ directory "compliance" do
90
+ directory "profiles/my_profile" do
91
+ file "inspec.yml", <<~FILE
92
+ ---
93
+ name: my-profile
94
+ FILE
95
+
96
+ directory "controls" do
97
+ file "my_control.rb", <<~FILE
98
+ control "my control" do
99
+ describe Dir.home do
100
+ it { should be_kind_of String }
101
+ end
102
+ end
103
+ FILE
104
+ end
105
+ end
106
+ end
107
+ file "attributes/default.rb", <<~FILE
108
+ default['audit']['reporter'] = "json-file"
109
+ default['audit']['json_file'] = {
110
+ "location" => "#{report_file}"
111
+ }
112
+ FILE
113
+ file "recipes/default.rb", <<~FILE
114
+ include_profile ".*::.*"
115
+ FILE
116
+ end
117
+ file "config/client.rb", <<~EOM
118
+ local_mode true
119
+ cookbook_path "#{path_to("cookbooks")}"
120
+ log_level :warn
121
+ EOM
122
+ end
123
+
124
+ it "should complete with success" do
125
+ result = shell_out!("#{chef_client} -c \"#{path_to("config/client.rb")}\" -r 'recipe[x]'", cwd: chef_dir)
126
+ result.error!
127
+
128
+ inspec_report = JSON.parse(File.read(report_file))
129
+ expect(inspec_report["profiles"].length).to eq(1)
130
+
131
+ profile = inspec_report["profiles"].first
132
+ expect(profile["name"]).to eq("my-profile")
133
+ expect(profile["controls"].length).to eq(1)
134
+
135
+ control = profile["controls"].first
136
+ expect(control["id"]).to eq("my control")
137
+ expect(control["results"].length).to eq(1)
138
+
139
+ result = control["results"].first
140
+ expect(result["status"]).to eq("passed")
141
+ end
142
+ end
82
143
  end
@@ -354,8 +354,8 @@ module ResourceActionSpec
354
354
  end
355
355
 
356
356
  it "allows overridden action to have a description separate from the action defined in the base resource" do
357
- expect(ActionJackson.action_description(:test1)).to eql "Original description"
358
- expect(ActionJackalope.action_description(:test1)).to eql "An old action with a new description"
357
+ expect(ActionJackson.new("ActionJackson", nil).action_description(:test1)).to eql "Original description"
358
+ expect(ActionJackalope.new("ActionJackalope", nil).action_description(:test1)).to eql "An old action with a new description"
359
359
  end
360
360
 
361
361
  it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do
data/spec/spec_helper.rb CHANGED
@@ -68,6 +68,7 @@ end
68
68
  require "spec/support/local_gems" if File.exist?(File.join(File.dirname(__FILE__), "support", "local_gems.rb"))
69
69
 
70
70
  # Explicitly require spec helpers that need to load first
71
+ require "spec/support/ruby_installer"
71
72
  require "spec/support/platform_helpers"
72
73
  require "spec/support/shared/unit/mock_shellout"
73
74
 
@@ -186,6 +187,8 @@ RSpec.configure do |config|
186
187
  config.filter_run_excluding not_rhel7: true if rhel7?
187
188
  config.filter_run_excluding not_intel_64bit: true if intel_64bit?
188
189
 
190
+ config.filter_run_excluding libarchive_loading_broken: true if aix? || amazon_linux? || rhel7?
191
+
189
192
  # these let us use chef: ">= 13" or ruby: "~> 2.0.0" or any other Gem::Dependency-style constraint
190
193
  config.filter_run_excluding chef: DependencyProc.with(Chef::VERSION)
191
194
  config.filter_run_excluding ruby: DependencyProc.with(RUBY_VERSION)
@@ -163,6 +163,10 @@ def aix?
163
163
  RUBY_PLATFORM.include?("aix")
164
164
  end
165
165
 
166
+ def amazon_linux?
167
+ ohai[:platform_family] == "amazon"
168
+ end
169
+
166
170
  def wpar?
167
171
  !((ohai[:virtualization] || {})[:wpar_no].nil?)
168
172
  end
@@ -0,0 +1,51 @@
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
+ def add_libarchive_dll_directory
18
+ require "ruby_installer"
19
+ libarchive_paths = Dir.glob("{#{Gem.dir},C:/hab}/**/libarchive.dll").map { |f| File.expand_path(f) }
20
+ if libarchive_paths.empty?
21
+ $stderr.puts <<~EOL
22
+ !!!!
23
+ We couldn't find a libarchive.dll in #{Gem.dir} or C:/hab
24
+
25
+ If this is running in a CI/CD environment, this may end up causing failures
26
+ in the tests for archive_file. If this is not running in a CI/CD
27
+ environment then it may be safe to ignore this. That is especially true if
28
+ you're not using the Ruby Installer as your Ruby runtime.
29
+ !!!!
30
+ EOL
31
+ return
32
+ end
33
+
34
+ $stderr.puts "\nFound the following libarchive paths:\n\n#{libarchive_paths.map { |f| "- #{f}\n" }.join}\n\n"
35
+ libarchive_path = libarchive_paths.first
36
+ libarchive_dir = File.dirname(libarchive_path)
37
+
38
+ if defined?(RubyInstaller::Build) && RubyInstaller::Build.methods.include?(:add_dll_directory)
39
+ $stderr.puts "Adding #{libarchive_dir} as a DLL load path using RubyInstaller::Build#add_dll_directory"
40
+ RubyInstaller::Build.add_dll_directory(libarchive_dir)
41
+ elsif defined?(RubyInstaller::Runtime) && RubyInstaller::Runtime.methods.include?(:add_dll_directory)
42
+ $stderr.puts "Adding #{libarchive_dir} as a DLL load path using RubyInstaller::Runtime#add_dll_directory"
43
+ RubyInstaller::Runtime.add_dll_directory(libarchive_dir)
44
+ else
45
+ $stderr.puts "Unable to find the right namespace to call #add_dll_directory! Please raise an issue on [GitHub](https://github.com/chef/chef/issues/new/choose)."
46
+ end
47
+ rescue LoadError
48
+ $stderr.puts "Failed to load ruby_installer. Assuming Ruby Installer is not being used."
49
+ end
50
+
51
+ add_libarchive_dll_directory if RUBY_PLATFORM =~ /mswin|mingw32|windows/
@@ -0,0 +1,104 @@
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
+
18
+ require "spec_helper"
19
+ require "tempfile"
20
+
21
+ describe Chef::Compliance::Input do
22
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
23
+ let(:data) { { "ssh-01" => { "expiration_date" => Date.jd(2463810), "justification" => "waived, yo", "run" => false } } }
24
+ let(:path) { "/var/chef/cache/cookbooks/acme_compliance/compliance/inputs/default.yml" }
25
+ let(:cookbook_name) { "acme_compliance" }
26
+ let(:input) { Chef::Compliance::Input.new(events, data, path, cookbook_name) }
27
+
28
+ it "has a cookbook_name" do
29
+ expect(input.cookbook_name).to eql(cookbook_name)
30
+ end
31
+
32
+ it "has a path" do
33
+ expect(input.path).to eql(path)
34
+ end
35
+
36
+ it "has a pathname based on the path" do
37
+ expect(input.pathname).to eql("default")
38
+ end
39
+
40
+ it "is disabled" do
41
+ expect(input.enabled).to eql(false)
42
+ expect(input.enabled?).to eql(false)
43
+ end
44
+
45
+ it "has an event handler" do
46
+ expect(input.events).to eql(events)
47
+ end
48
+
49
+ it "can be enabled by enable!" do
50
+ input.enable!
51
+ expect(input.enabled).to eql(true)
52
+ expect(input.enabled?).to eql(true)
53
+ end
54
+
55
+ it "enabling sends an event" do
56
+ expect(events).to receive(:compliance_input_enabled).with(input)
57
+ input.enable!
58
+ end
59
+
60
+ it "can be disabled by disable!" do
61
+ input.enable!
62
+ input.disable!
63
+ expect(input.enabled).to eql(false)
64
+ expect(input.enabled?).to eql(false)
65
+ end
66
+
67
+ it "has a #inspec_data method that renders the data" do
68
+ expect(input.inspec_data).to eql(data)
69
+ end
70
+
71
+ it "doesn't render the events in the inspect output" do
72
+ expect(input.inspect).not_to include("events")
73
+ end
74
+
75
+ it "inflates objects from YAML" do
76
+ string = <<~EOH
77
+ ssh-01:
78
+ expiration_date: 2033-07-31
79
+ run: false
80
+ justification: "waived, yo"
81
+ EOH
82
+ newinput = Chef::Compliance::Input.from_yaml(events, string, path, cookbook_name)
83
+ expect(newinput.data).to eql(data)
84
+ end
85
+
86
+ it "inflates objects from files" do
87
+ string = <<~EOH
88
+ ssh-01:
89
+ expiration_date: 2033-07-31
90
+ run: false
91
+ justification: "waived, yo"
92
+ EOH
93
+ tempfile = Tempfile.new("chef-compliance-test")
94
+ tempfile.write string
95
+ tempfile.close
96
+ newinput = Chef::Compliance::Input.from_file(events, tempfile.path, cookbook_name)
97
+ expect(newinput.data).to eql(data)
98
+ end
99
+
100
+ it "inflates objects from hashes" do
101
+ newinput = Chef::Compliance::Input.from_hash(events, data, path, cookbook_name)
102
+ expect(newinput.data).to eql(data)
103
+ end
104
+ end
@@ -0,0 +1,120 @@
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
+
18
+ require "spec_helper"
19
+ require "tempfile"
20
+
21
+ describe Chef::Compliance::Profile do
22
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
23
+ let(:data) { { "copyright" => "DevSec Hardening Framework Team", "copyright_email" => "hello@dev-sec.io", "license" => "Apache-2.0", "maintainer" => "DevSec Hardening Framework Team", "name" => "ssh-baseline", "summary" => "Test-suite for best-practice SSH hardening", "supports" => [{ "os-family" => "unix" }], "title" => "DevSec SSH Baseline", "version" => "2.6.4" } }
24
+ let(:path) { "/var/chef/cache/cookbooks/acme_compliance/compliance/profiles/thisdirectoryisnotthename/inspec.yml" }
25
+ let(:cookbook_name) { "acme_compliance" }
26
+ let(:profile) { Chef::Compliance::Profile.new(events, data, path, cookbook_name) }
27
+
28
+ it "has a cookbook_name" do
29
+ expect(profile.cookbook_name).to eql(cookbook_name)
30
+ end
31
+
32
+ it "has a path" do
33
+ expect(profile.path).to eql(path)
34
+ end
35
+
36
+ it "has a name based on the yml" do
37
+ expect(profile.name).to eql("ssh-baseline")
38
+ end
39
+
40
+ it "has a pathname based on the path" do
41
+ expect(profile.pathname).to eql("thisdirectoryisnotthename")
42
+ end
43
+
44
+ it "is disabled" do
45
+ expect(profile.enabled).to eql(false)
46
+ expect(profile.enabled?).to eql(false)
47
+ end
48
+
49
+ it "has an event handler" do
50
+ expect(profile.events).to eql(events)
51
+ end
52
+
53
+ it "can be enabled by enable!" do
54
+ profile.enable!
55
+ expect(profile.enabled).to eql(true)
56
+ expect(profile.enabled?).to eql(true)
57
+ end
58
+
59
+ it "enabling sends an event" do
60
+ expect(events).to receive(:compliance_profile_enabled).with(profile)
61
+ profile.enable!
62
+ end
63
+
64
+ it "can be disabled by disable!" do
65
+ profile.enable!
66
+ profile.disable!
67
+ expect(profile.enabled).to eql(false)
68
+ expect(profile.enabled?).to eql(false)
69
+ end
70
+
71
+ it "has a #inspec_data method that renders the path" do
72
+ expect(profile.inspec_data).to eql( { name: "ssh-baseline", path: "/var/chef/cache/cookbooks/acme_compliance/compliance/profiles/thisdirectoryisnotthename" } )
73
+ end
74
+
75
+ it "doesn't render the events in the inspect output" do
76
+ expect(profile.inspect).not_to include("events")
77
+ end
78
+
79
+ it "inflates objects from YAML" do
80
+ string = <<~EOH
81
+ name: ssh-baseline#{" "}
82
+ title: DevSec SSH Baseline#{" "}
83
+ maintainer: DevSec Hardening Framework Team#{" "}
84
+ copyright: DevSec Hardening Framework Team#{" "}
85
+ copyright_email: hello@dev-sec.io#{" "}
86
+ license: Apache-2.0#{" "}
87
+ summary: Test-suite for best-practice SSH hardening#{" "}
88
+ version: 2.6.4#{" "}
89
+ supports:#{" "}
90
+ - os-family: unix
91
+ EOH
92
+ newprofile = Chef::Compliance::Profile.from_yaml(events, string, path, cookbook_name)
93
+ expect(newprofile.data).to eql(data)
94
+ end
95
+
96
+ it "inflates objects from files" do
97
+ string = <<~EOH
98
+ name: ssh-baseline#{" "}
99
+ title: DevSec SSH Baseline#{" "}
100
+ maintainer: DevSec Hardening Framework Team#{" "}
101
+ copyright: DevSec Hardening Framework Team#{" "}
102
+ copyright_email: hello@dev-sec.io#{" "}
103
+ license: Apache-2.0#{" "}
104
+ summary: Test-suite for best-practice SSH hardening#{" "}
105
+ version: 2.6.4#{" "}
106
+ supports:#{" "}
107
+ - os-family: unix
108
+ EOH
109
+ tempfile = Tempfile.new("chef-compliance-test")
110
+ tempfile.write string
111
+ tempfile.close
112
+ newprofile = Chef::Compliance::Profile.from_file(events, tempfile.path, cookbook_name)
113
+ expect(newprofile.data).to eql(data)
114
+ end
115
+
116
+ it "inflates objects from hashes" do
117
+ newprofile = Chef::Compliance::Profile.from_hash(events, data, path, cookbook_name)
118
+ expect(newprofile.data).to eql(data)
119
+ end
120
+ end