chef 12.0.0.alpha.0 → 12.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -22,6 +22,8 @@ require 'openssl'
|
|
22
22
|
require 'ffi_yajl'
|
23
23
|
require 'chef/encrypted_data_bag_item'
|
24
24
|
require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
|
25
|
+
require 'chef/encrypted_data_bag_item/encryption_failure'
|
26
|
+
require 'chef/encrypted_data_bag_item/assertions'
|
25
27
|
|
26
28
|
class Chef::EncryptedDataBagItem
|
27
29
|
|
@@ -40,9 +42,11 @@ class Chef::EncryptedDataBagItem
|
|
40
42
|
Version1Encryptor.new(value, secret, iv)
|
41
43
|
when 2
|
42
44
|
Version2Encryptor.new(value, secret, iv)
|
45
|
+
when 3
|
46
|
+
Version3Encryptor.new(value, secret, iv)
|
43
47
|
else
|
44
48
|
raise UnsupportedEncryptedDataBagItemFormat,
|
45
|
-
"Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2'"
|
49
|
+
"Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2', '3'"
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
@@ -50,6 +54,8 @@ class Chef::EncryptedDataBagItem
|
|
50
54
|
attr_reader :key
|
51
55
|
attr_reader :plaintext_data
|
52
56
|
|
57
|
+
include Chef::EncryptedDataBagItem::Assertions
|
58
|
+
|
53
59
|
# Create a new Encryptor for +data+, which will be encrypted with the given
|
54
60
|
# +key+.
|
55
61
|
#
|
@@ -65,6 +71,11 @@ class Chef::EncryptedDataBagItem
|
|
65
71
|
@iv = iv && Base64.decode64(iv)
|
66
72
|
end
|
67
73
|
|
74
|
+
# Returns the used encryption algorithm
|
75
|
+
def algorithm
|
76
|
+
ALGORITHM
|
77
|
+
end
|
78
|
+
|
68
79
|
# Returns a wrapped and encrypted version of +plaintext_data+ suitable for
|
69
80
|
# using as the value in an encrypted data bag item.
|
70
81
|
def for_encrypted_item
|
@@ -72,27 +83,28 @@ class Chef::EncryptedDataBagItem
|
|
72
83
|
"encrypted_data" => encrypted_data,
|
73
84
|
"iv" => Base64.encode64(iv),
|
74
85
|
"version" => 1,
|
75
|
-
"cipher" =>
|
86
|
+
"cipher" => algorithm
|
76
87
|
}
|
77
88
|
end
|
78
89
|
|
79
90
|
# Generates or returns the IV.
|
80
91
|
def iv
|
81
|
-
# Generated IV comes from OpenSSL::Cipher
|
92
|
+
# Generated IV comes from OpenSSL::Cipher#random_iv
|
82
93
|
# This gets generated when +openssl_encryptor+ gets created.
|
83
94
|
openssl_encryptor if @iv.nil?
|
84
95
|
@iv
|
85
96
|
end
|
86
97
|
|
87
|
-
# Generates (and memoizes) an OpenSSL::Cipher
|
98
|
+
# Generates (and memoizes) an OpenSSL::Cipher object and configures
|
88
99
|
# it for the specified iv and encryption key.
|
89
100
|
def openssl_encryptor
|
90
101
|
@openssl_encryptor ||= begin
|
91
|
-
encryptor = OpenSSL::Cipher
|
102
|
+
encryptor = OpenSSL::Cipher.new(algorithm)
|
92
103
|
encryptor.encrypt
|
104
|
+
# We must set key before iv: https://bugs.ruby-lang.org/issues/8221
|
105
|
+
encryptor.key = OpenSSL::Digest::SHA256.digest(key)
|
93
106
|
@iv ||= encryptor.random_iv
|
94
107
|
encryptor.iv = @iv
|
95
|
-
encryptor.key = Digest::SHA256.digest(key)
|
96
108
|
encryptor
|
97
109
|
end
|
98
110
|
end
|
@@ -125,18 +137,77 @@ class Chef::EncryptedDataBagItem
|
|
125
137
|
"hmac" => hmac,
|
126
138
|
"iv" => Base64.encode64(iv),
|
127
139
|
"version" => 2,
|
128
|
-
"cipher" =>
|
140
|
+
"cipher" => algorithm
|
129
141
|
}
|
130
142
|
end
|
131
143
|
|
132
144
|
# Generates an HMAC-SHA2-256 of the encrypted data (encrypt-then-mac)
|
133
145
|
def hmac
|
134
146
|
@hmac ||= begin
|
135
|
-
digest = OpenSSL::Digest
|
147
|
+
digest = OpenSSL::Digest.new("sha256")
|
136
148
|
raw_hmac = OpenSSL::HMAC.digest(digest, key, encrypted_data)
|
137
149
|
Base64.encode64(raw_hmac)
|
138
150
|
end
|
139
151
|
end
|
140
152
|
end
|
153
|
+
|
154
|
+
class Version3Encryptor < Version1Encryptor
|
155
|
+
include Chef::EncryptedDataBagItem::Assertions
|
156
|
+
|
157
|
+
def initialize(plaintext_data, key, iv=nil)
|
158
|
+
super
|
159
|
+
assert_aead_requirements_met!(algorithm)
|
160
|
+
@auth_tag = nil
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns a wrapped and encrypted version of +plaintext_data+ suitable for
|
164
|
+
# using as the value in an encrypted data bag item.
|
165
|
+
def for_encrypted_item
|
166
|
+
{
|
167
|
+
"encrypted_data" => encrypted_data,
|
168
|
+
"iv" => Base64.encode64(iv),
|
169
|
+
"auth_tag" => Base64.encode64(auth_tag),
|
170
|
+
"version" => 3,
|
171
|
+
"cipher" => algorithm
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns the used encryption algorithm
|
176
|
+
def algorithm
|
177
|
+
AEAD_ALGORITHM
|
178
|
+
end
|
179
|
+
|
180
|
+
# Returns a wrapped and encrypted version of +plaintext_data+ suitable for
|
181
|
+
# Returns the auth_tag.
|
182
|
+
def auth_tag
|
183
|
+
# Generated auth_tag comes from OpenSSL::Cipher#auth_tag
|
184
|
+
# This must be generated after the data is encrypted
|
185
|
+
if @auth_tag.nil?
|
186
|
+
raise EncryptionFailure, "Internal Error: GCM authentication tag read before encryption"
|
187
|
+
end
|
188
|
+
@auth_tag
|
189
|
+
end
|
190
|
+
|
191
|
+
# Generates (and memoizes) an OpenSSL::Cipher object and configures
|
192
|
+
# it for the specified iv and encryption key using AEAD
|
193
|
+
def openssl_encryptor
|
194
|
+
@openssl_encryptor ||= begin
|
195
|
+
encryptor = super
|
196
|
+
encryptor.auth_data = ''
|
197
|
+
encryptor
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# Encrypts, Base64 encodes +serialized_data+ and gets the authentication tag
|
202
|
+
def encrypted_data
|
203
|
+
@encrypted_data ||= begin
|
204
|
+
enc_data_b64 = super
|
205
|
+
@auth_tag = openssl_encryptor.auth_tag
|
206
|
+
enc_data_b64
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
141
212
|
end
|
142
213
|
end
|
data/lib/chef/environment.rb
CHANGED
@@ -129,7 +129,7 @@ class Chef
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def to_json(*a)
|
132
|
-
|
132
|
+
Chef::JSONCompat.to_json(to_hash, *a)
|
133
133
|
end
|
134
134
|
|
135
135
|
def update_from!(o)
|
@@ -140,7 +140,6 @@ class Chef
|
|
140
140
|
self
|
141
141
|
end
|
142
142
|
|
143
|
-
|
144
143
|
def update_attributes_from_params(params)
|
145
144
|
unless params[:default_attributes].nil? || params[:default_attributes].size == 0
|
146
145
|
default_attributes(Chef::JSONCompat.from_json(params[:default_attributes]))
|
@@ -213,7 +212,6 @@ class Chef
|
|
213
212
|
end
|
214
213
|
end
|
215
214
|
|
216
|
-
|
217
215
|
def self.json_create(o)
|
218
216
|
environment = new
|
219
217
|
environment.name(o["name"])
|
data/lib/chef/exceptions.rb
CHANGED
@@ -83,6 +83,7 @@ class Chef
|
|
83
83
|
class RequestedUIDUnavailable < RuntimeError; end
|
84
84
|
class InvalidHomeDirectory < ArgumentError; end
|
85
85
|
class DsclCommandFailed < RuntimeError; end
|
86
|
+
class PlistUtilCommandFailed < RuntimeError; end
|
86
87
|
class UserIDNotFound < ArgumentError; end
|
87
88
|
class GroupIDNotFound < ArgumentError; end
|
88
89
|
class ConflictingMembersInGroup < ArgumentError; end
|
@@ -115,6 +116,7 @@ class Chef
|
|
115
116
|
class Win32ArchitectureIncorrect < RuntimeError; end
|
116
117
|
class ObsoleteDependencySyntax < ArgumentError; end
|
117
118
|
class InvalidDataBagPath < ArgumentError; end
|
119
|
+
class DuplicateDataBagItem < RuntimeError; end
|
118
120
|
|
119
121
|
# A different version of a cookbook was added to a
|
120
122
|
# VersionedRecipeList than the one already there.
|
@@ -131,6 +133,8 @@ class Chef
|
|
131
133
|
# Version constraints are not allowed in chef-solo
|
132
134
|
class IllegalVersionConstraint < NotImplementedError; end
|
133
135
|
|
136
|
+
class MetadataNotValid < StandardError; end
|
137
|
+
|
134
138
|
# File operation attempted but no permissions to perform it
|
135
139
|
class InsufficientPermissions < RuntimeError; end
|
136
140
|
|
@@ -194,7 +198,6 @@ class Chef
|
|
194
198
|
end
|
195
199
|
end
|
196
200
|
|
197
|
-
|
198
201
|
end
|
199
202
|
# Exception class for collecting multiple failures. Used when running
|
200
203
|
# delayed notifications so that chef can process each delayed
|
@@ -262,7 +265,7 @@ class Chef
|
|
262
265
|
"non_existent_cookbooks" => non_existent_cookbooks,
|
263
266
|
"cookbooks_with_no_versions" => cookbooks_with_no_matching_versions
|
264
267
|
}
|
265
|
-
|
268
|
+
Chef::JSONCompat.to_json(result, *a)
|
266
269
|
end
|
267
270
|
end
|
268
271
|
|
@@ -297,7 +300,7 @@ class Chef
|
|
297
300
|
"non_existent_cookbooks" => non_existent_cookbooks,
|
298
301
|
"most_constrained_cookbooks" => most_constrained_cookbooks
|
299
302
|
}
|
300
|
-
|
303
|
+
Chef::JSONCompat.to_json(result, *a)
|
301
304
|
end
|
302
305
|
end
|
303
306
|
|
@@ -331,6 +334,18 @@ class Chef
|
|
331
334
|
end
|
332
335
|
end
|
333
336
|
|
337
|
+
class ChecksumMismatch < RuntimeError
|
338
|
+
def initialize(res_cksum, cont_cksum)
|
339
|
+
super "Checksum on resource (#{res_cksum}) does not match checksum on content (#{cont_cksum})"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
334
343
|
class BadProxyURI < RuntimeError; end
|
344
|
+
|
345
|
+
# Raised by Chef::JSONCompat
|
346
|
+
class JSON
|
347
|
+
class EncodeError < RuntimeError; end
|
348
|
+
class ParseError < RuntimeError; end
|
349
|
+
end
|
335
350
|
end
|
336
351
|
end
|
data/lib/chef/formatters/base.rb
CHANGED
@@ -93,6 +93,13 @@ class Chef
|
|
93
93
|
|
94
94
|
def indent_by(amount)
|
95
95
|
@output.indent += amount
|
96
|
+
if @output.indent < 0
|
97
|
+
# This is left commented out for now. We need to uncomment it and fix at least one bug in
|
98
|
+
# the formatter, and then leave this line uncommented in the future.
|
99
|
+
#Chef::Log.warn "Internal Formatter Error -- Attempt to indent by negative number of spaces"
|
100
|
+
@output.indent = 0
|
101
|
+
end
|
102
|
+
@output.indent
|
96
103
|
end
|
97
104
|
|
98
105
|
# Input: a Formatters::ErrorDescription object.
|
@@ -56,7 +56,7 @@ class Chef
|
|
56
56
|
# * could be no read on the node
|
57
57
|
error_description.section("Authorization Error",<<-E)
|
58
58
|
This client is not authorized to read some of the information required to
|
59
|
-
access its
|
59
|
+
access its cookbooks (HTTP 403).
|
60
60
|
|
61
61
|
To access its cookbooks, a client needs to be able to read its environment and
|
62
62
|
all of the cookbooks in its expanded run list.
|
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
if @inflate_json_class
|
51
51
|
return_value = Chef::JSONCompat.from_json(http_response.body.chomp)
|
52
52
|
else
|
53
|
-
return_value = Chef::JSONCompat.
|
53
|
+
return_value = Chef::JSONCompat.parse(http_response.body.chomp)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
[http_response, rest_request, return_value]
|
data/lib/chef/json_compat.rb
CHANGED
@@ -18,7 +18,9 @@
|
|
18
18
|
# Wrapper class for interacting with JSON.
|
19
19
|
|
20
20
|
require 'ffi_yajl'
|
21
|
+
require 'json'
|
21
22
|
require 'ffi_yajl/json_gem' # XXX: parts of chef require JSON gem's Hash#to_json monkeypatch
|
23
|
+
require 'chef/exceptions'
|
22
24
|
|
23
25
|
class Chef
|
24
26
|
class JSONCompat
|
@@ -40,15 +42,24 @@ class Chef
|
|
40
42
|
|
41
43
|
class <<self
|
42
44
|
|
45
|
+
# API to use to avoid create_addtions
|
46
|
+
def parse(source, opts = {})
|
47
|
+
begin
|
48
|
+
FFI_Yajl::Parser.parse(source, opts)
|
49
|
+
rescue FFI_Yajl::ParseError => e
|
50
|
+
raise Chef::Exceptions::JSON::ParseError, e.message
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
43
54
|
# Just call the JSON gem's parse method with a modified :max_nesting field
|
44
55
|
def from_json(source, opts = {})
|
45
|
-
obj =
|
56
|
+
obj = parse(source, opts)
|
46
57
|
|
47
58
|
# JSON gem requires top level object to be a Hash or Array (otherwise
|
48
59
|
# you get the "must contain two octets" error). Yajl doesn't impose the
|
49
60
|
# same limitation. For compatibility, we re-impose this condition.
|
50
61
|
unless obj.kind_of?(Hash) or obj.kind_of?(Array)
|
51
|
-
raise JSON::
|
62
|
+
raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
|
52
63
|
end
|
53
64
|
|
54
65
|
# The old default in the json gem (which we are mimicing because we
|
@@ -88,14 +99,21 @@ class Chef
|
|
88
99
|
end
|
89
100
|
|
90
101
|
def to_json(obj, opts = nil)
|
91
|
-
|
102
|
+
begin
|
103
|
+
FFI_Yajl::Encoder.encode(obj, opts)
|
104
|
+
rescue FFI_Yajl::EncodeError => e
|
105
|
+
raise Chef::Exceptions::JSON::EncodeError, e.message
|
106
|
+
end
|
92
107
|
end
|
93
108
|
|
94
109
|
def to_json_pretty(obj, opts = nil)
|
95
|
-
|
110
|
+
opts ||= {}
|
111
|
+
options_map = {}
|
112
|
+
options_map[:pretty] = true
|
113
|
+
options_map[:indent] = opts[:indent] if opts.has_key?(:indent)
|
114
|
+
to_json(obj, options_map).chomp
|
96
115
|
end
|
97
116
|
|
98
|
-
|
99
117
|
# Map +json_class+ to a Class object. We use a +case+ instead of a Hash
|
100
118
|
# assigned to a constant because otherwise this file could not be loaded
|
101
119
|
# until all the constants were defined, which means you'd have to load
|
@@ -130,7 +148,7 @@ class Chef
|
|
130
148
|
when /^Chef::Resource/
|
131
149
|
Chef::Resource.find_subclass_by_name(json_class)
|
132
150
|
else
|
133
|
-
raise JSON::
|
151
|
+
raise Chef::Exceptions::JSON::ParseError, "Unsupported `json_class` type '#{json_class}'"
|
134
152
|
end
|
135
153
|
end
|
136
154
|
|
data/lib/chef/knife/bootstrap.rb
CHANGED
@@ -126,7 +126,7 @@ class Chef
|
|
126
126
|
:short => "-j JSON_ATTRIBS",
|
127
127
|
:long => "--json-attributes",
|
128
128
|
:description => "A JSON string to be added to the first run of chef-client",
|
129
|
-
:proc => lambda { |o|
|
129
|
+
:proc => lambda { |o| Chef::JSONCompat.parse(o) },
|
130
130
|
:default => {}
|
131
131
|
|
132
132
|
option :host_key_verify,
|
@@ -141,7 +141,7 @@ class Chef
|
|
141
141
|
:proc => Proc.new { |h|
|
142
142
|
Chef::Config[:knife][:hints] ||= Hash.new
|
143
143
|
name, path = h.split("=")
|
144
|
-
Chef::Config[:knife][:hints][name] = path ?
|
144
|
+
Chef::Config[:knife][:hints][name] = path ? Chef::JSONCompat.parse(::File.read(path)) : Hash.new }
|
145
145
|
|
146
146
|
option :secret,
|
147
147
|
:short => "-s SECRET",
|
@@ -47,7 +47,7 @@ class Chef
|
|
47
47
|
object = Chef::ApiClient.load(@client_name)
|
48
48
|
if object.validator
|
49
49
|
unless config[:delete_validators]
|
50
|
-
ui.fatal("You must specify --
|
50
|
+
ui.fatal("You must specify --delete-validators to delete the validator client #{@client_name}")
|
51
51
|
exit 2
|
52
52
|
end
|
53
53
|
end
|
@@ -41,7 +41,7 @@ class Chef
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def get_cookbook_list(items=10, start=0, cookbook_collection={})
|
44
|
-
cookbooks_url = "
|
44
|
+
cookbooks_url = "https://supermarket.getchef.com/api/v1/cookbooks?items=#{items}&start=#{start}"
|
45
45
|
cr = noauth_rest.get_rest(cookbooks_url)
|
46
46
|
cr["items"].each do |cookbook|
|
47
47
|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
|
@@ -29,7 +29,7 @@ class Chef
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def search_cookbook(query, items=10, start=0, cookbook_collection={})
|
32
|
-
cookbooks_url = "
|
32
|
+
cookbooks_url = "https://supermarket.getchef.com/api/v1/search?q=#{query}&items=#{items}&start=#{start}"
|
33
33
|
cr = noauth_rest.get_rest(cookbooks_url)
|
34
34
|
cr["items"].each do |cookbook|
|
35
35
|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
|
@@ -85,9 +85,9 @@ class Chef
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def do_upload(cookbook_filename, cookbook_category, user_id, user_secret_filename)
|
88
|
-
uri = "
|
88
|
+
uri = "https://supermarket.getchef.com/api/v1/cookbooks"
|
89
89
|
|
90
|
-
category_string = { 'category'=>cookbook_category }
|
90
|
+
category_string = Chef::JSONCompat.to_json({ 'category'=>cookbook_category })
|
91
91
|
|
92
92
|
http_resp = Chef::CookbookSiteStreamingUploader.post(uri, user_id, user_secret_filename, {
|
93
93
|
:tarball => File.open(cookbook_filename),
|
@@ -31,14 +31,14 @@ class Chef
|
|
31
31
|
def get_cookbook_data
|
32
32
|
case @name_args.length
|
33
33
|
when 1
|
34
|
-
noauth_rest.get_rest("
|
34
|
+
noauth_rest.get_rest("https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}")
|
35
35
|
when 2
|
36
|
-
noauth_rest.get_rest("
|
36
|
+
noauth_rest.get_rest("https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
def get_cookbook_list(items=10, start=0, cookbook_collection={})
|
41
|
-
cookbooks_url = "
|
41
|
+
cookbooks_url = "https://supermarket.getchef.com/api/v1/cookbooks?items=#{items}&start=#{start}"
|
42
42
|
cr = noauth_rest.get_rest(cookbooks_url)
|
43
43
|
cr["items"].each do |cookbook|
|
44
44
|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
|