chef 12.0.0.alpha.0-x86-mingw32 → 12.0.0.alpha.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +3 -5
- data/lib/chef/api_client.rb +1 -1
- data/lib/chef/application.rb +16 -8
- data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
- data/lib/chef/chef_fs/command_line.rb +1 -1
- data/lib/chef/chef_fs/file_system.rb +1 -1
- data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +3 -3
- data/lib/chef/chef_fs/file_system/cookbook_file.rb +2 -2
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -2
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -4
- data/lib/chef/config.rb +6 -5
- data/lib/chef/config_fetcher.rb +1 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +126 -43
- data/lib/chef/cookbook/metadata.rb +102 -53
- data/lib/chef/cookbook/syntax_check.rb +1 -1
- data/lib/chef/cookbook_loader.rb +62 -14
- data/lib/chef/cookbook_site_streaming_uploader.rb +12 -1
- data/lib/chef/cookbook_version.rb +13 -4
- data/lib/chef/data_bag.rb +28 -15
- data/lib/chef/data_bag_item.rb +5 -7
- data/lib/chef/digester.rb +5 -9
- data/lib/chef/dsl/recipe.rb +14 -0
- data/lib/chef/encrypted_data_bag_item.rb +1 -0
- data/lib/chef/encrypted_data_bag_item/assertions.rb +57 -0
- data/lib/chef/encrypted_data_bag_item/decryptor.rb +52 -28
- data/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb +37 -0
- data/lib/chef/encrypted_data_bag_item/encryption_failure.rb +22 -0
- data/lib/chef/encrypted_data_bag_item/encryptor.rb +79 -8
- data/lib/chef/environment.rb +1 -3
- data/lib/chef/exceptions.rb +18 -3
- data/lib/chef/formatters/base.rb +7 -0
- data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
- data/lib/chef/handler/json_file.rb +0 -1
- data/lib/chef/http/json_output.rb +1 -1
- data/lib/chef/json_compat.rb +24 -6
- data/lib/chef/knife/bootstrap.rb +2 -2
- data/lib/chef/knife/client_delete.rb +1 -1
- data/lib/chef/knife/cookbook_site_download.rb +1 -1
- data/lib/chef/knife/cookbook_site_list.rb +1 -1
- data/lib/chef/knife/cookbook_site_search.rb +1 -1
- data/lib/chef/knife/cookbook_site_share.rb +2 -2
- data/lib/chef/knife/cookbook_site_show.rb +3 -3
- data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
- data/lib/chef/knife/core/node_editor.rb +2 -3
- data/lib/chef/knife/core/ui.rb +2 -2
- data/lib/chef/knife/deps.rb +2 -3
- data/lib/chef/mixin/shell_out.rb +1 -1
- data/lib/chef/mixin/windows_architecture_helper.rb +1 -0
- data/lib/chef/node.rb +1 -2
- data/lib/chef/platform/provider_mapping.rb +33 -6
- data/lib/chef/provider.rb +0 -2
- data/lib/chef/provider/cookbook_file/content.rb +1 -1
- data/lib/chef/provider/cron.rb +11 -0
- data/lib/chef/provider/deploy.rb +3 -2
- data/lib/chef/provider/deploy/revision.rb +2 -2
- data/lib/chef/provider/env.rb +1 -1
- data/lib/chef/provider/env/windows.rb +5 -9
- data/lib/chef/provider/file.rb +84 -33
- data/lib/chef/provider/git.rb +2 -1
- data/lib/chef/provider/group/aix.rb +17 -2
- data/lib/chef/provider/group/dscl.rb +27 -9
- data/lib/chef/provider/group/pw.rb +8 -1
- data/lib/chef/provider/http_request.rb +4 -4
- data/lib/chef/provider/log.rb +4 -14
- data/lib/chef/provider/mount/mount.rb +2 -2
- data/lib/chef/provider/package/ips.rb +17 -23
- data/lib/chef/provider/package/paludis.rb +2 -2
- data/lib/chef/provider/package/rpm.rb +2 -2
- data/lib/chef/provider/package/rubygems.rb +2 -0
- data/lib/chef/provider/package/yum.rb +2 -0
- data/lib/chef/provider/package/zypper.rb +1 -1
- data/lib/chef/provider/remote_file/cache_control_data.rb +2 -2
- data/lib/chef/provider/service/windows.rb +87 -21
- data/lib/chef/provider/user/aix.rb +95 -0
- data/lib/chef/provider/user/dscl.rb +544 -156
- data/lib/chef/provider/user/useradd.rb +1 -0
- data/lib/chef/providers.rb +1 -0
- data/lib/chef/resource.rb +4 -3
- data/lib/chef/resource/freebsd_package.rb +10 -2
- data/lib/chef/resource/paludis_package.rb +1 -0
- data/lib/chef/resource/scm.rb +10 -0
- data/lib/chef/resource/user.rb +27 -0
- data/lib/chef/resource/windows_service.rb +53 -0
- data/lib/chef/resource_collection.rb +23 -12
- data/lib/chef/resource_reporter.rb +10 -10
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/role.rb +3 -3
- data/lib/chef/run_list.rb +6 -3
- data/lib/chef/user.rb +1 -1
- data/lib/chef/util/diff.rb +1 -2
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version_constraint.rb +4 -4
- data/spec/data/cookbooks/angrybash/metadata.rb +2 -0
- data/spec/data/cookbooks/apache2/metadata.rb +2 -0
- data/spec/data/cookbooks/borken/metadata.rb +2 -0
- data/spec/data/cookbooks/ignorken/metadata.rb +2 -0
- data/spec/data/cookbooks/java/metadata.rb +2 -0
- data/spec/data/cookbooks/name-mismatch-versionnumber/README.md +4 -0
- data/spec/data/cookbooks/name-mismatch-versionnumber/metadata.rb +8 -0
- data/spec/data/cookbooks/name-mismatch-versionnumber/recipes/default.rb +8 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/not_a_template.erb +2 -0
- data/spec/data/cookbooks/preseed/metadata.rb +2 -0
- data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/README.md +4 -0
- data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/metadata.rb +13 -0
- data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/recipes/default.rb +8 -0
- data/spec/data/invalid-metadata-chef-repo/invalid-metadata/README.md +4 -0
- data/spec/data/invalid-metadata-chef-repo/invalid-metadata/metadata.rb +10 -0
- data/spec/data/invalid-metadata-chef-repo/invalid-metadata/recipes/default.rb +8 -0
- data/spec/data/mac_users/10.7-8.plist.xml +559 -0
- data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
- data/spec/data/mac_users/10.7.plist.xml +559 -0
- data/spec/data/mac_users/10.7.shadow.xml +11 -0
- data/spec/data/mac_users/10.8.plist.xml +559 -0
- data/spec/data/mac_users/10.8.shadow.xml +21 -0
- data/spec/data/mac_users/10.9.plist.xml +560 -0
- data/spec/data/mac_users/10.9.shadow.xml +21 -0
- data/spec/data/object_loader/environments/test.json +2 -0
- data/spec/data/object_loader/environments/test_json_class.json +2 -0
- data/spec/data/object_loader/nodes/test.json +2 -0
- data/spec/data/object_loader/nodes/test_json_class.json +2 -0
- data/spec/data/object_loader/roles/test.json +2 -0
- data/spec/data/object_loader/roles/test_json_class.json +2 -0
- data/spec/functional/resource/bff_spec.rb +1 -1
- data/spec/functional/resource/cron_spec.rb +20 -1
- data/spec/functional/resource/env_spec.rb +137 -0
- data/spec/functional/resource/group_spec.rb +7 -5
- data/spec/functional/resource/remote_file_spec.rb +12 -1
- data/spec/functional/resource/user/dscl_spec.rb +198 -0
- data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +175 -37
- data/spec/integration/client/client_spec.rb +6 -4
- data/spec/integration/client/ipv6_spec.rb +16 -14
- data/spec/integration/knife/chef_fs_data_store_spec.rb +57 -46
- data/spec/integration/knife/chef_repo_path_spec.rb +105 -78
- data/spec/integration/knife/chef_repository_file_system_spec.rb +100 -84
- data/spec/integration/knife/chefignore_spec.rb +76 -46
- data/spec/integration/knife/common_options_spec.rb +16 -21
- data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -3
- data/spec/integration/knife/delete_spec.rb +66 -46
- data/spec/integration/knife/deps_spec.rb +145 -94
- data/spec/integration/knife/diff_spec.rb +176 -110
- data/spec/integration/knife/download_spec.rb +229 -133
- data/spec/integration/knife/list_spec.rb +62 -54
- data/spec/integration/knife/raw_spec.rb +24 -9
- data/spec/integration/knife/redirection_spec.rb +2 -2
- data/spec/integration/knife/serve_spec.rb +2 -2
- data/spec/integration/knife/show_spec.rb +32 -26
- data/spec/integration/knife/upload_spec.rb +308 -165
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +10 -8
- data/spec/integration/solo/solo_spec.rb +22 -11
- data/spec/spec_helper.rb +3 -0
- data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
- data/spec/support/platform_helpers.rb +12 -0
- data/spec/support/shared/functional/file_resource.rb +10 -0
- data/spec/support/shared/integration/chef_zero_support.rb +130 -0
- data/spec/support/shared/integration/integration_helper.rb +100 -98
- data/spec/support/shared/integration/knife_support.rb +0 -1
- data/spec/support/shared/unit/provider/file.rb +6 -4
- data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +10 -1
- data/spec/unit/api_client/registration_spec.rb +83 -74
- data/spec/unit/application_spec.rb +32 -9
- data/spec/unit/cookbook/cookbook_version_loader_spec.rb +179 -0
- data/spec/unit/cookbook/metadata_spec.rb +190 -150
- data/spec/unit/cookbook/syntax_check_spec.rb +3 -2
- data/spec/unit/cookbook_loader_spec.rb +114 -53
- data/spec/unit/{cookbook_site_streaming_uploader.rb → cookbook_site_streaming_uploader_spec.rb} +21 -1
- data/spec/unit/data_bag_spec.rb +88 -13
- data/spec/unit/deprecation_spec.rb +1 -2
- data/spec/unit/encrypted_data_bag_item_spec.rb +145 -9
- data/spec/unit/environment_spec.rb +1 -1
- data/spec/unit/formatters/base_spec.rb +48 -0
- data/spec/unit/json_compat_spec.rb +48 -17
- data/spec/unit/knife/client_delete_spec.rb +4 -4
- data/spec/unit/knife/client_show_spec.rb +15 -5
- data/spec/unit/knife/cookbook_site_download_spec.rb +1 -1
- data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
- data/spec/unit/knife/data_bag_from_file_spec.rb +0 -2
- data/spec/unit/knife/data_bag_show_spec.rb +23 -14
- data/spec/unit/knife/node_show_spec.rb +32 -15
- data/spec/unit/knife/role_show_spec.rb +59 -0
- data/spec/unit/platform_spec.rb +10 -0
- data/spec/unit/provider/deploy_spec.rb +4 -0
- data/spec/unit/provider/env_spec.rb +19 -0
- data/spec/unit/provider/git_spec.rb +22 -2
- data/spec/unit/provider/group/dscl_spec.rb +38 -1
- data/spec/unit/provider/group/pw_spec.rb +2 -2
- data/spec/unit/provider/http_request_spec.rb +8 -8
- data/spec/unit/provider/log_spec.rb +33 -53
- data/spec/unit/provider/mount/mount_spec.rb +12 -3
- data/spec/unit/provider/package/ips_spec.rb +96 -63
- data/spec/unit/provider/package/paludis_spec.rb +5 -5
- data/spec/unit/provider/package/rpm_spec.rb +12 -0
- data/spec/unit/provider/package/zypper_spec.rb +28 -16
- data/spec/unit/provider/service/windows_spec.rb +77 -17
- data/spec/unit/provider/user/dscl_spec.rb +659 -264
- data/spec/unit/provider/user/useradd_spec.rb +1 -0
- data/spec/unit/recipe_spec.rb +41 -0
- data/spec/unit/resource/scm_spec.rb +11 -0
- data/spec/unit/resource/user_spec.rb +4 -0
- data/spec/unit/resource/windows_service_spec.rb +46 -0
- data/spec/unit/resource_collection_spec.rb +33 -0
- data/spec/unit/resource_reporter_spec.rb +48 -0
- data/spec/unit/resource_spec.rb +9 -2
- data/spec/unit/role_spec.rb +6 -0
- data/spec/unit/version_constraint_spec.rb +28 -0
- metadata +61 -4
@@ -46,7 +46,7 @@ describe Chef::Deprecation do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
method_snapshot_file = File.join(CHEF_SPEC_DATA, "file-providers-method-snapshot-chef-11-4.json")
|
49
|
-
method_snapshot =
|
49
|
+
method_snapshot = Chef::JSONCompat.parse(File.open(method_snapshot_file).read())
|
50
50
|
|
51
51
|
method_snapshot.each do |class_name, old_methods|
|
52
52
|
class_object = class_from_string(class_name)
|
@@ -83,4 +83,3 @@ describe Chef::Deprecation do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
end
|
86
|
-
|
@@ -23,7 +23,7 @@ module Version0Encryptor
|
|
23
23
|
def self.encrypt_value(plaintext_data, key)
|
24
24
|
data = plaintext_data.to_yaml
|
25
25
|
|
26
|
-
cipher = OpenSSL::Cipher
|
26
|
+
cipher = OpenSSL::Cipher.new("aes-256-cbc")
|
27
27
|
cipher.encrypt
|
28
28
|
cipher.pkcs5_keyivgen(key)
|
29
29
|
encrypted_bytes = cipher.update(data)
|
@@ -39,14 +39,14 @@ describe Chef::EncryptedDataBagItem::Encryptor do
|
|
39
39
|
let(:key) { "passwd" }
|
40
40
|
|
41
41
|
it "encrypts to format version 1 by default" do
|
42
|
-
encryptor.should
|
42
|
+
encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version1Encryptor)
|
43
43
|
end
|
44
44
|
|
45
45
|
describe "generating a random IV" do
|
46
46
|
it "generates a new IV for each encryption pass" do
|
47
47
|
encryptor2 = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data, key)
|
48
48
|
|
49
|
-
# No API in ruby OpenSSL to get the iv
|
49
|
+
# No API in ruby OpenSSL to get the iv is used for the encryption back
|
50
50
|
# out. Instead we test if the encrypted data is the same. If it *is* the
|
51
51
|
# same, we assume the IV was the same each time.
|
52
52
|
encryptor.encrypted_data.should_not eq encryptor2.encrypted_data
|
@@ -56,7 +56,7 @@ describe Chef::EncryptedDataBagItem::Encryptor do
|
|
56
56
|
describe "when encrypting a non-hash non-array value" do
|
57
57
|
let(:plaintext_data) { 5 }
|
58
58
|
it "serializes the value in a de-serializable way" do
|
59
|
-
Chef::JSONCompat.from_json(
|
59
|
+
Chef::JSONCompat.from_json(encryptor.serialized_data)["json_wrapper"].should eq 5
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
@@ -78,10 +78,10 @@ describe Chef::EncryptedDataBagItem::Encryptor do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it "creates a version 2 encryptor" do
|
81
|
-
encryptor.should
|
81
|
+
encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor)
|
82
82
|
end
|
83
83
|
|
84
|
-
it "generates an hmac based on ciphertext
|
84
|
+
it "generates an hmac based on ciphertext with different iv" do
|
85
85
|
encryptor2 = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data, key)
|
86
86
|
encryptor.hmac.should_not eq(encryptor2.hmac)
|
87
87
|
end
|
@@ -92,6 +92,74 @@ describe Chef::EncryptedDataBagItem::Encryptor do
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
+
describe "when using version 3 format" do
|
96
|
+
before do
|
97
|
+
Chef::Config[:data_bag_encrypt_version] = 3
|
98
|
+
end
|
99
|
+
|
100
|
+
context "on supported platforms", :ruby_gte_20_and_openssl_gte_101 do
|
101
|
+
|
102
|
+
it "creates a version 3 encryptor" do
|
103
|
+
encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version3Encryptor)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "generates different authentication tags" do
|
107
|
+
encryptor3 = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data, key)
|
108
|
+
encryptor.for_encrypted_item # required to generate the auth_tag
|
109
|
+
encryptor3.for_encrypted_item
|
110
|
+
encryptor.auth_tag.should_not eq(encryptor3.auth_tag)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "includes the auth_tag in the envelope" do
|
114
|
+
final_data = encryptor.for_encrypted_item
|
115
|
+
final_data["auth_tag"].should eq(Base64::encode64(encryptor.auth_tag))
|
116
|
+
end
|
117
|
+
|
118
|
+
it "throws an error if auth tag is read before encrypting the data" do
|
119
|
+
lambda { encryptor.auth_tag }.should raise_error(Chef::EncryptedDataBagItem::EncryptionFailure)
|
120
|
+
end
|
121
|
+
|
122
|
+
end # context on supported platforms
|
123
|
+
|
124
|
+
context "on unsupported platforms" do
|
125
|
+
let(:aead_algorithm) { Chef::EncryptedDataBagItem::AEAD_ALGORITHM }
|
126
|
+
|
127
|
+
it "throws an error warning about the Ruby version if it has no GCM support" do
|
128
|
+
# Force OpenSSL with AEAD support
|
129
|
+
OpenSSL::Cipher.stub(:ciphers).and_return([ aead_algorithm ])
|
130
|
+
# Ruby without AEAD support
|
131
|
+
OpenSSL::Cipher.should_receive(:method_defined?).with(:auth_data=).and_return(false)
|
132
|
+
lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "throws an error warning about the OpenSSL version if it has no GCM support" do
|
136
|
+
# Force Ruby with AEAD support
|
137
|
+
OpenSSL::Cipher.stub(:method_defined?).with(:auth_data=).and_return(true)
|
138
|
+
# OpenSSL without AEAD support
|
139
|
+
OpenSSL::Cipher.should_receive(:ciphers).and_return([])
|
140
|
+
lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
|
141
|
+
end
|
142
|
+
|
143
|
+
context "on platforms with old Ruby", :ruby_lt_20 do
|
144
|
+
|
145
|
+
it "throws an error warning about the Ruby version" do
|
146
|
+
lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
|
147
|
+
end
|
148
|
+
|
149
|
+
end # context on platforms with old Ruby
|
150
|
+
|
151
|
+
context "on platforms with old OpenSSL", :openssl_lt_101 do
|
152
|
+
|
153
|
+
it "throws an error warning about the OpenSSL version" do
|
154
|
+
lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
|
155
|
+
end
|
156
|
+
|
157
|
+
end # context on platforms with old OpenSSL
|
158
|
+
|
159
|
+
end # context on unsupported platforms
|
160
|
+
|
161
|
+
end # when using version 3 format
|
162
|
+
|
95
163
|
end
|
96
164
|
|
97
165
|
describe Chef::EncryptedDataBagItem::Decryptor do
|
@@ -101,17 +169,85 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
101
169
|
let(:encryption_key) { "passwd" }
|
102
170
|
let(:decryption_key) { encryption_key }
|
103
171
|
|
172
|
+
context "when decrypting a version 3 (JSON+aes-256-gcm+random iv+auth tag) encrypted value" do
|
173
|
+
|
174
|
+
context "on supported platforms", :ruby_gte_20_and_openssl_gte_101 do
|
175
|
+
|
176
|
+
let(:encrypted_value) do
|
177
|
+
Chef::EncryptedDataBagItem::Encryptor::Version3Encryptor.new(plaintext_data, encryption_key).for_encrypted_item
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:bogus_auth_tag) { "bogus_auth_tag" }
|
181
|
+
|
182
|
+
it "decrypts the encrypted value" do
|
183
|
+
decryptor.decrypted_data.should eq({"json_wrapper" => plaintext_data}.to_json)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "unwraps the encrypted data and returns it" do
|
187
|
+
decryptor.for_decrypted_item.should eq plaintext_data
|
188
|
+
end
|
189
|
+
|
190
|
+
it "rejects the data if the authentication tag is wrong" do
|
191
|
+
encrypted_value["auth_tag"] = bogus_auth_tag
|
192
|
+
lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "rejects the data if the authentication tag is missing" do
|
196
|
+
encrypted_value.delete("auth_tag")
|
197
|
+
lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
|
198
|
+
end
|
199
|
+
|
200
|
+
end # context on supported platforms
|
201
|
+
|
202
|
+
context "on unsupported platforms" do
|
203
|
+
let(:encrypted_value) do
|
204
|
+
{
|
205
|
+
"encrypted_data" => "",
|
206
|
+
"iv" => "",
|
207
|
+
"version" => 3,
|
208
|
+
"cipher" => "aes-256-cbc",
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
context "on platforms with old Ruby", :ruby_lt_20 do
|
213
|
+
|
214
|
+
it "throws an error warning about the Ruby version" do
|
215
|
+
lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
|
216
|
+
end
|
217
|
+
|
218
|
+
end # context on platforms with old Ruby
|
219
|
+
|
220
|
+
context "on platforms with old OpenSSL", :openssl_lt_101 do
|
221
|
+
|
222
|
+
it "throws an error warning about the OpenSSL version" do
|
223
|
+
lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
|
224
|
+
end
|
225
|
+
|
226
|
+
end # context on unsupported platforms
|
227
|
+
|
228
|
+
end # context on platforms with old OpenSSL
|
229
|
+
|
230
|
+
end # context when decrypting a version 3
|
231
|
+
|
104
232
|
context "when decrypting a version 2 (JSON+aes-256-cbc+hmac-sha256+random iv) encrypted value" do
|
105
233
|
let(:encrypted_value) do
|
106
234
|
Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor.new(plaintext_data, encryption_key).for_encrypted_item
|
107
235
|
end
|
108
236
|
|
109
237
|
let(:bogus_hmac) do
|
110
|
-
digest = OpenSSL::Digest
|
238
|
+
digest = OpenSSL::Digest.new("sha256")
|
111
239
|
raw_hmac = OpenSSL::HMAC.digest(digest, "WRONG", encrypted_value["encrypted_data"])
|
112
240
|
Base64.encode64(raw_hmac)
|
113
241
|
end
|
114
242
|
|
243
|
+
it "decrypts the encrypted value" do
|
244
|
+
decryptor.decrypted_data.should eq({"json_wrapper" => plaintext_data}.to_json)
|
245
|
+
end
|
246
|
+
|
247
|
+
it "unwraps the encrypted data and returns it" do
|
248
|
+
decryptor.for_decrypted_item.should eq plaintext_data
|
249
|
+
end
|
250
|
+
|
115
251
|
it "rejects the data if the hmac is wrong" do
|
116
252
|
encrypted_value["hmac"] = bogus_hmac
|
117
253
|
lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
|
@@ -131,7 +267,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
131
267
|
end
|
132
268
|
|
133
269
|
it "selects the correct strategy for version 1" do
|
134
|
-
decryptor.should
|
270
|
+
decryptor.should be_a_instance_of Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
|
135
271
|
end
|
136
272
|
|
137
273
|
it "decrypts the encrypted value" do
|
@@ -191,7 +327,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
191
327
|
end
|
192
328
|
|
193
329
|
it "selects the correct strategy for version 0" do
|
194
|
-
decryptor.should
|
330
|
+
decryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Decryptor::Version0Decryptor)
|
195
331
|
end
|
196
332
|
|
197
333
|
it "decrypts the encrypted value" do
|
@@ -420,7 +420,7 @@ describe Chef::Environment do
|
|
420
420
|
"description" => "desc",
|
421
421
|
"chef_type" => "environment"
|
422
422
|
}
|
423
|
-
IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(
|
423
|
+
IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(Chef::JSONCompat.to_json(environment_hash))
|
424
424
|
environment = Chef::Environment.load('foo')
|
425
425
|
|
426
426
|
environment.should be_a_kind_of(Chef::Environment)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Lamont Granquist (<lamont@getchef.com>)
|
3
|
+
#
|
4
|
+
# Copyright:: Copyright (c) 2012 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'spec_helper'
|
21
|
+
|
22
|
+
describe Chef::Formatters::Base do
|
23
|
+
let(:out) { double("out") }
|
24
|
+
let(:err) { double("err") }
|
25
|
+
let(:formatter) { Chef::Formatters::Base.new(out, err) }
|
26
|
+
|
27
|
+
it "starts with an indentation of zero" do
|
28
|
+
expect(formatter.output.indent).to eql(0)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "increments it to two correctly" do
|
32
|
+
formatter.indent_by(2)
|
33
|
+
expect(formatter.output.indent).to eql(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "increments it and then decrements it corectly" do
|
37
|
+
formatter.indent_by(2)
|
38
|
+
formatter.indent_by(-2)
|
39
|
+
expect(formatter.output.indent).to eql(0)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "does not allow negative indentation" do
|
43
|
+
formatter.indent_by(-2)
|
44
|
+
expect(formatter.output.indent).to eql(0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
@@ -21,48 +21,79 @@ require 'chef/json_compat'
|
|
21
21
|
|
22
22
|
describe Chef::JSONCompat do
|
23
23
|
|
24
|
-
describe "with JSON containing an existing class" do
|
25
|
-
let(:json){'{"json_class": "Chef::Role"}'}
|
24
|
+
describe "#from_json with JSON containing an existing class" do
|
25
|
+
let(:json) { '{"json_class": "Chef::Role"}' }
|
26
|
+
|
27
|
+
it "returns an instance of the class instead of a Hash" do
|
28
|
+
expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#from_json with JSON containing comments" do
|
33
|
+
let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
|
34
|
+
|
26
35
|
it "returns an instance of the class instead of a Hash" do
|
27
|
-
Chef::JSONCompat.from_json(json).class.
|
36
|
+
expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#parse with JSON containing comments" do
|
41
|
+
let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
|
42
|
+
|
43
|
+
it "returns a Hash" do
|
44
|
+
expect(Chef::JSONCompat.parse(json).class).to eq Hash
|
28
45
|
end
|
29
46
|
end
|
30
47
|
|
31
48
|
describe 'with JSON containing "Chef::Sandbox" as a json_class value' do
|
32
49
|
require 'chef/sandbox' # Only needed for this test
|
33
|
-
|
50
|
+
|
51
|
+
let(:json) { '{"json_class": "Chef::Sandbox", "arbitrary": "data"}' }
|
52
|
+
|
34
53
|
it "returns a Hash, because Chef::Sandbox is a dummy class" do
|
35
|
-
Chef::JSONCompat.from_json(json).
|
54
|
+
expect(Chef::JSONCompat.from_json(json)).to eq({"json_class" => "Chef::Sandbox", "arbitrary" => "data"})
|
36
55
|
end
|
37
56
|
end
|
38
57
|
|
39
|
-
describe "
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
describe "when pretty printing an object that defines #to_json" do
|
59
|
+
class Foo
|
60
|
+
def to_json(*a)
|
61
|
+
{'foo' => 1234}.to_json(*a)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should work" do
|
66
|
+
f = Foo.new
|
67
|
+
expect(Chef::JSONCompat.to_json_pretty(f)).to eql("{\n \"foo\": 1234\n}\n")
|
43
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "with a file with 300 or less nested entries" do
|
72
|
+
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json.json')) }
|
73
|
+
let(:hash) { Chef::JSONCompat.from_json(json) }
|
44
74
|
|
45
75
|
describe "when a big json file is loaded" do
|
46
76
|
it "should create a Hash from the file" do
|
47
|
-
|
77
|
+
expect(hash).to be_kind_of(Hash)
|
48
78
|
end
|
79
|
+
|
49
80
|
it "should has 'test' as a 300th nested value" do
|
50
|
-
|
81
|
+
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
51
82
|
end
|
52
83
|
end
|
53
84
|
end
|
85
|
+
|
54
86
|
describe "with a file with more than 300 nested entries" do
|
55
|
-
|
56
|
-
|
57
|
-
@hash = Chef::JSONCompat.from_json(@json, {:max_nesting => 301})
|
58
|
-
end
|
87
|
+
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json_plus_one.json')) }
|
88
|
+
let(:hash) { Chef::JSONCompat.from_json(json, {:max_nesting => 301}) }
|
59
89
|
|
60
90
|
describe "when a big json file is loaded" do
|
61
91
|
it "should create a Hash from the file" do
|
62
|
-
|
92
|
+
expect(hash).to be_kind_of(Hash)
|
63
93
|
end
|
94
|
+
|
64
95
|
it "should has 'test' as a 301st nested value" do
|
65
|
-
|
96
|
+
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
66
97
|
end
|
67
98
|
end
|
68
99
|
end
|
@@ -50,7 +50,7 @@ describe Chef::Knife::ClientDelete do
|
|
50
50
|
Chef::ApiClient.should_receive(:load).and_return(@client)
|
51
51
|
end
|
52
52
|
|
53
|
-
it 'should delete non-validator client if --
|
53
|
+
it 'should delete non-validator client if --delete-validators is not set' do
|
54
54
|
@knife.config[:delete_validators] = false
|
55
55
|
@client.should_receive(:destroy).and_return(@client)
|
56
56
|
@knife.should_receive(:msg)
|
@@ -58,7 +58,7 @@ describe Chef::Knife::ClientDelete do
|
|
58
58
|
@knife.run
|
59
59
|
end
|
60
60
|
|
61
|
-
it 'should delete non-validator client if --
|
61
|
+
it 'should delete non-validator client if --delete-validators is set' do
|
62
62
|
@knife.config[:delete_validators] = true
|
63
63
|
@client.should_receive(:destroy).and_return(@client)
|
64
64
|
@knife.should_receive(:msg)
|
@@ -66,13 +66,13 @@ describe Chef::Knife::ClientDelete do
|
|
66
66
|
@knife.run
|
67
67
|
end
|
68
68
|
|
69
|
-
it 'should not delete validator client if --
|
69
|
+
it 'should not delete validator client if --delete-validators is not set' do
|
70
70
|
@client.validator(true)
|
71
71
|
@knife.ui.should_receive(:fatal)
|
72
72
|
lambda { @knife.run}.should raise_error(SystemExit)
|
73
73
|
end
|
74
74
|
|
75
|
-
it 'should delete validator client if --
|
75
|
+
it 'should delete validator client if --delete-validators is set' do
|
76
76
|
@knife.config[:delete_validators] = true
|
77
77
|
@client.should_receive(:destroy).and_return(@client)
|
78
78
|
@knife.should_receive(:msg)
|
@@ -27,16 +27,26 @@ describe Chef::Knife::ClientShow do
|
|
27
27
|
|
28
28
|
describe 'run' do
|
29
29
|
it 'should list the client' do
|
30
|
-
Chef::ApiClient.
|
31
|
-
@knife.
|
30
|
+
expect(Chef::ApiClient).to receive(:load).with('adam').and_return(@client_mock)
|
31
|
+
expect(@knife).to receive(:format_for_display).with(@client_mock)
|
32
32
|
@knife.run
|
33
33
|
end
|
34
34
|
|
35
|
+
it 'should pretty print json' do
|
36
|
+
@knife.config[:format] = 'json'
|
37
|
+
@stdout = StringIO.new
|
38
|
+
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
39
|
+
fake_client_contents = {"foo"=>"bar", "baz"=>"qux"}
|
40
|
+
expect(Chef::ApiClient).to receive(:load).with('adam').and_return(fake_client_contents)
|
41
|
+
@knife.run
|
42
|
+
expect(@stdout.string).to eql("{\n \"foo\": \"bar\",\n \"baz\": \"qux\"\n}\n")
|
43
|
+
end
|
44
|
+
|
35
45
|
it 'should print usage and exit when a client name is not provided' do
|
36
46
|
@knife.name_args = []
|
37
|
-
@knife.
|
38
|
-
@knife.ui.
|
39
|
-
|
47
|
+
expect(@knife).to receive(:show_usage)
|
48
|
+
expect(@knife.ui).to receive(:fatal)
|
49
|
+
expect { @knife.run }.to raise_error(SystemExit)
|
40
50
|
end
|
41
51
|
end
|
42
52
|
end
|