chef 17.4.38 → 17.7.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/chef.gemspec +3 -0
  4. data/lib/chef/application/base.rb +11 -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/client.rb +1 -2
  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/runner.rb +47 -5
  13. data/lib/chef/compliance/waiver.rb +115 -0
  14. data/lib/chef/compliance/waiver_collection.rb +143 -0
  15. data/lib/chef/data_collector/run_end_message.rb +1 -1
  16. data/lib/chef/dsl/compliance.rb +38 -0
  17. data/lib/chef/dsl/reader_helpers.rb +51 -0
  18. data/lib/chef/dsl/reboot_pending.rb +1 -1
  19. data/lib/chef/dsl/recipe.rb +4 -2
  20. data/lib/chef/dsl/secret.rb +2 -4
  21. data/lib/chef/dsl/universal.rb +2 -0
  22. data/lib/chef/event_dispatch/base.rb +44 -2
  23. data/lib/chef/exceptions.rb +10 -0
  24. data/lib/chef/formatters/doc.rb +46 -0
  25. data/lib/chef/http/basic_client.rb +15 -7
  26. data/lib/chef/http.rb +7 -3
  27. data/lib/chef/provider/cron.rb +4 -1
  28. data/lib/chef/provider/file.rb +2 -0
  29. data/lib/chef/provider/git.rb +1 -1
  30. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  31. data/lib/chef/provider/link.rb +2 -2
  32. data/lib/chef/provider/registry_key.rb +3 -2
  33. data/lib/chef/provider/remote_file/http.rb +1 -1
  34. data/lib/chef/provider/subversion.rb +5 -5
  35. data/lib/chef/provider/template.rb +1 -1
  36. data/lib/chef/resource/archive_file.rb +17 -14
  37. data/lib/chef/resource/chef_client_scheduled_task.rb +45 -2
  38. data/lib/chef/resource/chocolatey_config.rb +14 -14
  39. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  40. data/lib/chef/resource/chocolatey_source.rb +24 -2
  41. data/lib/chef/resource/directory.rb +1 -1
  42. data/lib/chef/resource/file/verification/json.rb +50 -0
  43. data/lib/chef/resource/file/verification/yaml.rb +52 -0
  44. data/lib/chef/resource/habitat_install.rb +3 -3
  45. data/lib/chef/resource/inspec_input.rb +127 -0
  46. data/lib/chef/resource/inspec_waiver.rb +184 -0
  47. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  48. data/lib/chef/resource/kernel_module.rb +27 -2
  49. data/lib/chef/resource/macos_userdefaults.rb +43 -128
  50. data/lib/chef/resource/mount.rb +1 -1
  51. data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
  52. data/lib/chef/resource/powershell_package_source.rb +234 -70
  53. data/lib/chef/resource/registry_key.rb +36 -48
  54. data/lib/chef/resource/remote_file.rb +98 -2
  55. data/lib/chef/resource/timezone.rb +2 -2
  56. data/lib/chef/resource/user_ulimit.rb +1 -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_printer.rb +1 -1
  60. data/lib/chef/resource/windows_uac.rb +3 -1
  61. data/lib/chef/resource/windows_update_settings.rb +3 -3
  62. data/lib/chef/resource/windows_user_privilege.rb +1 -1
  63. data/lib/chef/resource.rb +1 -1
  64. data/lib/chef/resource_reporter.rb +1 -1
  65. data/lib/chef/resources.rb +2 -0
  66. data/lib/chef/run_context/cookbook_compiler.rb +112 -28
  67. data/lib/chef/run_context.rb +31 -1
  68. data/lib/chef/secret_fetcher/akeyless_vault.rb +57 -0
  69. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +1 -1
  70. data/lib/chef/secret_fetcher/azure_key_vault.rb +63 -9
  71. data/lib/chef/secret_fetcher/base.rb +1 -1
  72. data/lib/chef/secret_fetcher/hashi_vault.rb +100 -0
  73. data/lib/chef/secret_fetcher.rb +8 -3
  74. data/lib/chef/version.rb +1 -1
  75. data/lib/chef/win32/version.rb +2 -1
  76. data/spec/data/archive_file/test_archive.tar.gz +0 -0
  77. data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
  78. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  79. data/spec/functional/resource/archive_file_spec.rb +87 -0
  80. data/spec/functional/resource/dsc_script_spec.rb +2 -2
  81. data/spec/functional/resource/group_spec.rb +5 -1
  82. data/spec/functional/resource/link_spec.rb +8 -0
  83. data/spec/functional/resource/macos_userdefaults_spec.rb +119 -0
  84. data/spec/functional/resource/powershell_package_source_spec.rb +5 -6
  85. data/spec/functional/resource/registry_spec.rb +81 -81
  86. data/spec/functional/win32/registry_spec.rb +8 -8
  87. data/spec/integration/compliance/compliance_spec.rb +60 -0
  88. data/spec/spec_helper.rb +3 -0
  89. data/spec/support/platform_helpers.rb +4 -0
  90. data/spec/support/ruby_installer.rb +51 -0
  91. data/spec/unit/compliance/input_spec.rb +104 -0
  92. data/spec/unit/compliance/profile_spec.rb +120 -0
  93. data/spec/unit/compliance/waiver_spec.rb +104 -0
  94. data/spec/unit/data_collector_spec.rb +24 -1
  95. data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
  96. data/spec/unit/http/basic_client_spec.rb +30 -0
  97. data/spec/unit/http_spec.rb +8 -2
  98. data/spec/unit/mixin/default_paths_spec.rb +1 -1
  99. data/spec/unit/mixin/securable_spec.rb +3 -3
  100. data/spec/unit/provider/cron_spec.rb +45 -0
  101. data/spec/unit/provider/link_spec.rb +13 -7
  102. data/spec/unit/provider/package/rubygems_spec.rb +5 -5
  103. data/spec/unit/provider/package/windows_spec.rb +1 -1
  104. data/spec/unit/provider/registry_key_spec.rb +4 -4
  105. data/spec/unit/provider/remote_file/http_spec.rb +10 -0
  106. data/spec/unit/provider/service/windows_spec.rb +5 -5
  107. data/spec/unit/provider/subversion_spec.rb +4 -4
  108. data/spec/unit/provider/template_spec.rb +2 -2
  109. data/spec/unit/provider/windows_env_spec.rb +1 -1
  110. data/spec/unit/provider/zypper_repository_spec.rb +1 -1
  111. data/spec/unit/resource/archive_file_spec.rb +414 -3
  112. data/spec/unit/resource/chef_client_scheduled_task_spec.rb +69 -0
  113. data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
  114. data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
  115. data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
  116. data/spec/unit/resource/file/verification/json_spec.rb +72 -0
  117. data/spec/unit/resource/file/verification/yaml_spec.rb +67 -0
  118. data/spec/unit/resource/inspec_input_spec.rb +300 -0
  119. data/spec/unit/resource/inspec_waiver_spec.rb +312 -0
  120. data/spec/unit/resource/kernel_module_spec.rb +2 -1
  121. data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
  122. data/spec/unit/resource/mount_spec.rb +10 -0
  123. data/spec/unit/resource/powershell_package_source_spec.rb +63 -62
  124. data/spec/unit/resource/registry_key_spec.rb +10 -10
  125. data/spec/unit/resource/user_ulimit_spec.rb +14 -1
  126. data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
  127. data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
  128. data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
  129. data/spec/unit/resource/windows_task_spec.rb +3 -3
  130. data/spec/unit/resource_reporter_spec.rb +2 -2
  131. data/spec/unit/resource_spec.rb +5 -0
  132. data/spec/unit/secret_fetcher/akeyless_vault_spec.rb +37 -0
  133. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
  134. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +80 -0
  135. data/spec/unit/util/backup_spec.rb +1 -1
  136. data/spec/unit/win32/registry_spec.rb +3 -3
  137. data/tasks/rspec.rb +2 -1
  138. metadata +75 -6
@@ -25,6 +25,11 @@ describe Chef::Resource::ChefClientScheduledTask do
25
25
  let(:resource) { Chef::Resource::ChefClientScheduledTask.new("fakey_fakerton", run_context) }
26
26
  let(:provider) { resource.provider_for_action(:add) }
27
27
 
28
+ before do
29
+ allow(ENV).to receive(:[]).and_call_original
30
+ allow(ENV).to receive(:[]).with("COMSPEC").and_return("C:\\Windows\\System32\\cmd.exe")
31
+ end
32
+
28
33
  it "sets the default action as :add" do
29
34
  expect(resource.action).to eql([:add])
30
35
  end
@@ -73,11 +78,75 @@ describe Chef::Resource::ChefClientScheduledTask do
73
78
  expect(resource.chef_binary_path).to eql("C:/opscode/chef/bin/chef-client")
74
79
  end
75
80
 
81
+ context "priority" do
82
+ it "default value is 7" do
83
+ expect(resource.priority).to eq(7)
84
+ end
85
+
86
+ it "raise error when priority value less than 0" do
87
+ expect { resource.priority(-1) }.to raise_error(Chef::Exceptions::ValidationFailed, "Option priority's value -1 should be in range of 0 to 10!")
88
+ end
89
+
90
+ it "raise error when priority values is greater than 10" do
91
+ expect { resource.priority 11 }.to raise_error(Chef::Exceptions::ValidationFailed, "Option priority's value 11 should be in range of 0 to 10!")
92
+ end
93
+ end
94
+
76
95
  it "supports :add and :remove actions" do
77
96
  expect { resource.action :add }.not_to raise_error
78
97
  expect { resource.action :remove }.not_to raise_error
79
98
  end
80
99
 
100
+ it "expects use_consistent_splay to be true when set" do
101
+ resource.use_consistent_splay = true
102
+ expect(resource.use_consistent_splay).to eql(true)
103
+ end
104
+
105
+ context "when configured to use a consistent splay" do
106
+ before do
107
+ node.automatic_attrs[:shard_seed] = nil
108
+ allow(node).to receive(:name).and_return("test_node")
109
+ resource.config_directory = "C:/chef" # Allows local unit testing on nix flavors
110
+ resource.use_consistent_splay = true
111
+ end
112
+
113
+ it "sleeps the same amount each time based on splay before running the task" do
114
+ expect(provider.full_command).to eql("C:\\Windows\\System32\\cmd.exe /c \"C:/windows/system32/windowspowershell/v1.0/powershell.exe Start-Sleep -s 272 && C:/opscode/chef/bin/chef-client -L C:/chef/log/client.log -c C:/chef/client.rb\"")
115
+ end
116
+ end
117
+
118
+ describe "#consistent_splay_command" do
119
+ context "when use_consistent_splay is false" do
120
+ it "returns nil" do
121
+ expect(provider.consistent_splay_command).to eql(nil)
122
+ end
123
+ end
124
+
125
+ context "when use_consistent_splay is true" do
126
+ before do
127
+ resource.use_consistent_splay true
128
+ allow(provider).to receive(:splay_sleep_time).and_return(222)
129
+ end
130
+
131
+ it "returns a powershell sleep command to be appended to the chef client run command" do
132
+ expect(provider.consistent_splay_command).to eql("C:/windows/system32/windowspowershell/v1.0/powershell.exe Start-Sleep -s 222 && ")
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "#splay_sleep_time" do
138
+ it "uses shard_seed attribute if present" do
139
+ node.automatic_attrs[:shard_seed] = "73399073"
140
+ expect(provider.splay_sleep_time(300)).to satisfy { |v| v >= 0 && v <= 300 }
141
+ end
142
+
143
+ it "uses a hex conversion of a md5 hash of the splay if present" do
144
+ node.automatic_attrs[:shard_seed] = nil
145
+ allow(node).to receive(:name).and_return("test_node")
146
+ expect(provider.splay_sleep_time(300)).to satisfy { |v| v >= 0 && v <= 300 }
147
+ end
148
+ end
149
+
81
150
  describe "#client_cmd" do
82
151
  it "creates a valid command if using all default properties" do
83
152
  expect(provider.client_cmd).to eql("C:/opscode/chef/bin/chef-client -L /etc/chef/log/client.log -c /etc/chef/client.rb") | eql("C:/opscode/chef/bin/chef-client -L C:\\chef/log/client.log -c C:\\chef/client.rb")
@@ -41,7 +41,7 @@ describe Chef::Resource::ChocolateyConfig do
41
41
  # we save off the ENV and set ALLUSERSPROFILE so these specs will work on *nix and non-C drive Windows installs
42
42
  before(:each) do
43
43
  @original_env = ENV.to_hash
44
- ENV["ALLUSERSPROFILE"] = 'C:\ProgramData'
44
+ ENV["ALLUSERSPROFILE"] = "C:\\ProgramData"
45
45
  end
46
46
 
47
47
  after(:each) do
@@ -41,7 +41,7 @@ describe Chef::Resource::ChocolateyFeature do
41
41
  # we save off the ENV and set ALLUSERSPROFILE so these specs will work on *nix and non-C drive Windows installs
42
42
  before(:each) do
43
43
  @original_env = ENV.to_hash
44
- ENV["ALLUSERSPROFILE"] = 'C:\ProgramData'
44
+ ENV["ALLUSERSPROFILE"] = "C:\\ProgramData"
45
45
  end
46
46
 
47
47
  after(:each) do
@@ -54,7 +54,7 @@ describe Chef::Resource::ChocolateySource do
54
54
  allow(resource).to receive(:provider_for_action).and_return(enable_provider)
55
55
  allow(resource.class).to receive(:new).and_return(current_resource)
56
56
  @original_env = ENV.to_hash
57
- ENV["ALLUSERSPROFILE"] = 'C:\ProgramData'
57
+ ENV["ALLUSERSPROFILE"] = "C:\\ProgramData"
58
58
  end
59
59
 
60
60
  after(:each) do
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Antony Thomas (<antonydeepak@gmail.com>)
3
+ # Copyright:: Copyright (c) Facebook, Inc. and its affiliates.
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::Resource::File::Verification::Json do
22
+ let(:parent_resource) { Chef::Resource.new("llama") }
23
+
24
+ before(:all) do
25
+ @valid_json = "valid-#{Time.now.to_i}.json"
26
+ f = File.new(@valid_json, "w")
27
+ f.write('{
28
+ "foo": "bar"
29
+ }')
30
+ f.close
31
+
32
+ @invalid_json = "invalid-#{Time.now.to_i}.json"
33
+ f = File.new(@invalid_json, "w")
34
+ f.write("{
35
+ 'foo': 'bar'
36
+ }")
37
+ f.close
38
+
39
+ @empty_json = "empty-#{Time.now.to_i}.json"
40
+ File.new(@empty_json, "w").close
41
+ end
42
+
43
+ context "verify" do
44
+ it "returns true for valid json" do
45
+ v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {})
46
+ expect(v.verify(@valid_json)).to eq(true)
47
+ end
48
+
49
+ it "returns false for invalid json" do
50
+ v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {})
51
+ expect(v.verify(@invalid_json)).to eq(false)
52
+ end
53
+
54
+ it "returns true for empty file" do
55
+ # Expectation here is different from that of default JSON parser included in ruby 2.4+.
56
+ # The default parser considers empty string as invalid JSON
57
+ # https://stackoverflow.com/questions/30621802/why-does-json-parse-fail-with-the-empty-string,
58
+ # however JSONCompat parses an empty string to `nil`.
59
+ # We are retaining the behavior of JSONCompat for two reasons
60
+ # - It is universal inside Chef codebase
61
+ # - It can be helpful to not throw an error when a `file` or `template` is empty
62
+ v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {})
63
+ expect(v.verify(@empty_json)).to eq(true)
64
+ end
65
+ end
66
+
67
+ after(:all) do
68
+ File.delete(@valid_json)
69
+ File.delete(@invalid_json)
70
+ File.delete(@empty_json)
71
+ end
72
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Author:: Antony Thomas (<antonydeepak@gmail.com>)
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::Resource::File::Verification::Yaml do
22
+ let(:parent_resource) { Chef::Resource.new("llama") }
23
+
24
+ before(:all) do
25
+ @valid_yaml = "valid-#{Time.now.to_i}.yaml"
26
+ f = File.new(@valid_yaml, "w")
27
+ f.write("# comment
28
+ svc:
29
+ mysqlPassword: sepppasswd
30
+ ")
31
+ f.close
32
+
33
+ @invalid_yaml = "invalid-#{Time.now.to_i}.yaml"
34
+ f = File.new(@invalid_yaml, "w")
35
+ f.write("# comment
36
+ svc:
37
+ mysqlPassword: 'sepppasswd
38
+ ")
39
+ f.close
40
+
41
+ @empty_yaml = "empty-#{Time.now.to_i}.yaml"
42
+ File.new(@empty_yaml, "w").close
43
+ end
44
+
45
+ context "verify" do
46
+ it "returns true for valid yaml" do
47
+ v = Chef::Resource::File::Verification::Yaml.new(parent_resource, :yaml, {})
48
+ expect(v.verify(@valid_yaml)).to eq(true)
49
+ end
50
+
51
+ it "returns false for invalid yaml" do
52
+ v = Chef::Resource::File::Verification::Yaml.new(parent_resource, :yaml, {})
53
+ expect(v.verify(@invalid_yaml)).to eq(false)
54
+ end
55
+
56
+ it "returns true for empty file" do
57
+ v = Chef::Resource::File::Verification::Yaml.new(parent_resource, :yaml, {})
58
+ expect(v.verify(@empty_yaml)).to eq(true)
59
+ end
60
+ end
61
+
62
+ after(:all) do
63
+ File.delete(@valid_yaml)
64
+ File.delete(@invalid_yaml)
65
+ File.delete(@empty_yaml)
66
+ end
67
+ end
@@ -0,0 +1,300 @@
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
+
20
+ describe Chef::Resource::InspecInput do
21
+ def load_input(filename)
22
+ path = "/var/chef/cache/cookbooks/acme_compliance/compliance/inputs/#{filename}"
23
+ run_context.input_collection << Chef::Compliance::Input.from_yaml(events, input_yaml, path, "acme_compliance")
24
+ end
25
+
26
+ let(:node) { Chef::Node.new }
27
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
28
+ let(:run_context) do
29
+ Chef::RunContext.new(node, {}, events).tap do |rc|
30
+ end
31
+ end
32
+ let(:collection) { double("resource collection") }
33
+ let(:input_yaml) do
34
+ <<~EOH
35
+ ssh_custom_path: "/whatever2"
36
+ EOH
37
+ end
38
+ let(:input_json) do
39
+ <<~EOH
40
+ { "ssh_custom_path": "/whatever2" }
41
+ EOH
42
+ end
43
+ let(:input_toml) do
44
+ <<~EOH
45
+ ssh_custom_path = "/whatever2"
46
+ EOH
47
+ end
48
+ let(:input_hash) do
49
+ { ssh_custom_path: "/whatever2" }
50
+ end
51
+ let(:resource) do
52
+ Chef::Resource::InspecInput.new("ssh-01", run_context)
53
+ end
54
+ let(:provider) { resource.provider_for_action(:add) }
55
+
56
+ before do
57
+ allow(run_context).to receive(:resource_collection).and_return(collection)
58
+ end
59
+
60
+ it "sets the default action as :add" do
61
+ expect(resource.action).to eql([:add])
62
+ end
63
+
64
+ context "with a input in a cookbook" do
65
+ it "enables the input by the name of the cookbook" do
66
+ load_input("default.yml")
67
+ resource.name "acme_compliance"
68
+ resource.run_action(:add)
69
+ expect(run_context.input_collection.first).to be_enabled
70
+ expect(resource).not_to be_updated_by_last_action
71
+ end
72
+
73
+ it "enables the input with a regular expression for the cookbook" do
74
+ load_input("default.yml")
75
+ resource.name "acme_comp.*"
76
+ resource.run_action(:add)
77
+ expect(run_context.input_collection.first).to be_enabled
78
+ expect(resource).not_to be_updated_by_last_action
79
+ end
80
+
81
+ it "enables the input with an explicit name" do
82
+ load_input("default.yml")
83
+ resource.name "acme_compliance::default"
84
+ resource.run_action(:add)
85
+ expect(run_context.input_collection.first).to be_enabled
86
+ expect(resource).not_to be_updated_by_last_action
87
+ end
88
+
89
+ it "fails when the cookbook name is wrong" do
90
+ load_input("default.yml")
91
+ resource.name "evil_compliance"
92
+ expect { resource.run_action(:add) }.to raise_error(StandardError)
93
+ expect(resource).not_to be_updated_by_last_action
94
+ end
95
+
96
+ it "enables the input when its not named default" do
97
+ load_input("ssh01.yml")
98
+ resource.name "acme_compliance::ssh01"
99
+ resource.run_action(:add)
100
+ expect(run_context.input_collection.first).to be_enabled
101
+ expect(resource).not_to be_updated_by_last_action
102
+ end
103
+
104
+ it "fails when it is not named default and you attempt to enable the default" do
105
+ load_input("ssh01.yml")
106
+ resource.name "acme_compliance"
107
+ expect { resource.run_action(:add) }.to raise_error(StandardError)
108
+ expect(resource).not_to be_updated_by_last_action
109
+ end
110
+
111
+ it "succeeds with a regexp that matches the cookbook name" do
112
+ load_input("ssh01.yml")
113
+ resource.name "acme_comp.*::ssh01"
114
+ resource.run_action(:add)
115
+ expect(run_context.input_collection.first).to be_enabled
116
+ expect(resource).not_to be_updated_by_last_action
117
+ end
118
+
119
+ it "succeeds with a regexp that matches the file name" do
120
+ load_input("ssh01.yml")
121
+ resource.name "acme_compliance::ssh.*"
122
+ resource.run_action(:add)
123
+ expect(run_context.input_collection.first).to be_enabled
124
+ expect(resource).not_to be_updated_by_last_action
125
+ end
126
+
127
+ it "succeeds with a regexps for both the file name and cookbook name" do
128
+ load_input("ssh01.yml")
129
+ resource.name "acme_comp.*::ssh.*"
130
+ resource.run_action(:add)
131
+ expect(run_context.input_collection.first).to be_enabled
132
+ expect(resource).not_to be_updated_by_last_action
133
+ end
134
+
135
+ it "fails with regexps that do not match" do
136
+ load_input("ssh01.yml")
137
+ resource.name "evil_comp.*::etcd.*"
138
+ expect { resource.run_action(:add) }.to raise_error(StandardError)
139
+ end
140
+
141
+ it "substring matches without regexps should fail when they are at the end" do
142
+ load_input("ssh01.yml")
143
+ resource.name "acme_complianc::ssh0"
144
+ expect { resource.run_action(:add) }.to raise_error(StandardError)
145
+ end
146
+
147
+ it "substring matches without regexps should fail when they are at the start" do
148
+ load_input("ssh01.yml")
149
+ resource.name "cme_compliance::sh01"
150
+ expect { resource.run_action(:add) }.to raise_error(StandardError)
151
+ end
152
+ end
153
+
154
+ context "with a input in a file" do
155
+ it "loads a YAML file" do
156
+ tempfile = Tempfile.new(["spec-compliance-test", ".yaml"])
157
+ tempfile.write input_yaml
158
+ tempfile.close
159
+ resource.name tempfile.path
160
+
161
+ resource.run_action(:add)
162
+
163
+ expect(run_context.input_collection.first).to be_enabled
164
+ expect(run_context.input_collection.size).to be 1
165
+ expect(run_context.input_collection.first.cookbook_name).to be nil
166
+ expect(run_context.input_collection.first.path).to be nil
167
+ expect(run_context.input_collection.first.pathname).to be nil
168
+ expect(resource).not_to be_updated_by_last_action
169
+ end
170
+
171
+ it "loads a YAML file in a source attribute" do
172
+ tempfile = Tempfile.new(["spec-compliance-test", ".yaml"])
173
+ tempfile.write input_yaml
174
+ tempfile.close
175
+ resource.name "my-resource-name"
176
+ resource.source tempfile.path
177
+
178
+ resource.run_action(:add)
179
+
180
+ expect(run_context.input_collection.first).to be_enabled
181
+ expect(run_context.input_collection.size).to be 1
182
+ expect(run_context.input_collection.first.cookbook_name).to be nil
183
+ expect(run_context.input_collection.first.path).to be nil
184
+ expect(run_context.input_collection.first.pathname).to be nil
185
+ expect(resource).not_to be_updated_by_last_action
186
+ end
187
+
188
+ it "loads a YML file" do
189
+ tempfile = Tempfile.new(["spec-compliance-test", ".yml"])
190
+ tempfile.write input_yaml
191
+ tempfile.close
192
+ resource.name tempfile.path
193
+
194
+ resource.run_action(:add)
195
+
196
+ expect(run_context.input_collection.first).to be_enabled
197
+ expect(run_context.input_collection.size).to be 1
198
+ expect(run_context.input_collection.first.cookbook_name).to be nil
199
+ expect(run_context.input_collection.first.path).to be nil
200
+ expect(run_context.input_collection.first.pathname).to be nil
201
+ expect(resource).not_to be_updated_by_last_action
202
+ end
203
+
204
+ it "loads a YML file using the source attribute" do
205
+ tempfile = Tempfile.new(["spec-compliance-test", ".yml"])
206
+ tempfile.write input_yaml
207
+ tempfile.close
208
+ resource.name "my-resource-name"
209
+ resource.source tempfile.path
210
+
211
+ resource.run_action(:add)
212
+
213
+ expect(run_context.input_collection.first).to be_enabled
214
+ expect(run_context.input_collection.size).to be 1
215
+ expect(run_context.input_collection.first.cookbook_name).to be nil
216
+ expect(run_context.input_collection.first.path).to be nil
217
+ expect(run_context.input_collection.first.pathname).to be nil
218
+ expect(resource).not_to be_updated_by_last_action
219
+ end
220
+
221
+ it "loads a JSON file" do
222
+ tempfile = Tempfile.new(["spec-compliance-test", ".json"])
223
+ tempfile.write input_json
224
+ tempfile.close
225
+ resource.name tempfile.path
226
+
227
+ resource.run_action(:add)
228
+
229
+ expect(run_context.input_collection.first).to be_enabled
230
+ expect(run_context.input_collection.size).to be 1
231
+ expect(run_context.input_collection.first.cookbook_name).to be nil
232
+ expect(run_context.input_collection.first.path).to be nil
233
+ expect(run_context.input_collection.first.pathname).to be nil
234
+ expect(resource).not_to be_updated_by_last_action
235
+ end
236
+
237
+ it "loads a JSON file using the source attribute" do
238
+ tempfile = Tempfile.new(["spec-compliance-test", ".json"])
239
+ tempfile.write input_json
240
+ tempfile.close
241
+ resource.name "my-resource-name"
242
+ resource.source tempfile.path
243
+
244
+ resource.run_action(:add)
245
+
246
+ expect(run_context.input_collection.first).to be_enabled
247
+ expect(run_context.input_collection.size).to be 1
248
+ expect(run_context.input_collection.first.cookbook_name).to be nil
249
+ expect(run_context.input_collection.first.path).to be nil
250
+ expect(run_context.input_collection.first.pathname).to be nil
251
+ expect(resource).not_to be_updated_by_last_action
252
+ end
253
+
254
+ it "loads a TOML file" do
255
+ tempfile = Tempfile.new(["spec-compliance-test", ".toml"])
256
+ tempfile.write input_toml
257
+ tempfile.close
258
+ resource.name tempfile.path
259
+
260
+ resource.run_action(:add)
261
+
262
+ expect(run_context.input_collection.first).to be_enabled
263
+ expect(run_context.input_collection.size).to be 1
264
+ expect(run_context.input_collection.first.cookbook_name).to be nil
265
+ expect(run_context.input_collection.first.path).to be nil
266
+ expect(run_context.input_collection.first.pathname).to be nil
267
+ expect(resource).not_to be_updated_by_last_action
268
+ end
269
+
270
+ it "loads a TOML file using the source attribute" do
271
+ tempfile = Tempfile.new(["spec-compliance-test", ".toml"])
272
+ tempfile.write input_toml
273
+ tempfile.close
274
+ resource.name "my-resource-name"
275
+ resource.source tempfile.path
276
+
277
+ resource.run_action(:add)
278
+
279
+ expect(run_context.input_collection.first).to be_enabled
280
+ expect(run_context.input_collection.size).to be 1
281
+ expect(run_context.input_collection.first.cookbook_name).to be nil
282
+ expect(run_context.input_collection.first.path).to be nil
283
+ expect(run_context.input_collection.first.pathname).to be nil
284
+ expect(resource).not_to be_updated_by_last_action
285
+ end
286
+
287
+ it "loads a Hash" do
288
+ resource.source input_hash
289
+
290
+ resource.run_action(:add)
291
+
292
+ expect(run_context.input_collection.first).to be_enabled
293
+ expect(run_context.input_collection.size).to be 1
294
+ expect(run_context.input_collection.first.cookbook_name).to be nil
295
+ expect(run_context.input_collection.first.path).to be nil
296
+ expect(run_context.input_collection.first.pathname).to be nil
297
+ expect(resource).not_to be_updated_by_last_action
298
+ end
299
+ end
300
+ end