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
data/lib/chef/data_bag.rb
CHANGED
@@ -54,16 +54,16 @@ class Chef
|
|
54
54
|
|
55
55
|
def to_hash
|
56
56
|
result = {
|
57
|
-
|
57
|
+
'name' => @name,
|
58
58
|
'json_class' => self.class.name,
|
59
|
-
|
59
|
+
'chef_type' => 'data_bag',
|
60
60
|
}
|
61
61
|
result
|
62
62
|
end
|
63
63
|
|
64
64
|
# Serialize this object as a hash
|
65
65
|
def to_json(*a)
|
66
|
-
|
66
|
+
Chef::JSONCompat.to_json(to_hash, *a)
|
67
67
|
end
|
68
68
|
|
69
69
|
def chef_server_rest
|
@@ -83,11 +83,15 @@ class Chef
|
|
83
83
|
|
84
84
|
def self.list(inflate=false)
|
85
85
|
if Chef::Config[:solo]
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
paths = Array(Chef::Config[:data_bag_path])
|
87
|
+
names = []
|
88
|
+
paths.each do |path|
|
89
|
+
unless File.directory?(path)
|
90
|
+
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' is invalid"
|
91
|
+
end
|
89
92
|
|
90
|
-
|
93
|
+
names += Dir.glob(File.join(path, "*")).map{|f|File.basename(f)}.sort
|
94
|
+
end
|
91
95
|
names.inject({}) {|h, n| h[n] = n; h}
|
92
96
|
else
|
93
97
|
if inflate
|
@@ -105,15 +109,25 @@ class Chef
|
|
105
109
|
# Load a Data Bag by name via either the RESTful API or local data_bag_path if run in solo mode
|
106
110
|
def self.load(name)
|
107
111
|
if Chef::Config[:solo]
|
108
|
-
|
109
|
-
|
110
|
-
|
112
|
+
paths = Array(Chef::Config[:data_bag_path])
|
113
|
+
data_bag = {}
|
114
|
+
paths.each do |path|
|
115
|
+
unless File.directory?(path)
|
116
|
+
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' is invalid"
|
117
|
+
end
|
118
|
+
|
119
|
+
Dir.glob(File.join(path, name.to_s, "*.json")).inject({}) do |bag, f|
|
120
|
+
item = Chef::JSONCompat.from_json(IO.read(f))
|
111
121
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
122
|
+
# Check if we have multiple items with similar names (ids) and raise if their content differs
|
123
|
+
if data_bag.has_key?(item["id"]) && data_bag[item["id"]] != item
|
124
|
+
raise Chef::Exceptions::DuplicateDataBagItem, "Data bag '#{name}' has items with the same name '#{item["id"]}' but different content."
|
125
|
+
else
|
126
|
+
data_bag[item["id"]] = item
|
127
|
+
end
|
128
|
+
end
|
116
129
|
end
|
130
|
+
return data_bag
|
117
131
|
else
|
118
132
|
Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data/#{name}")
|
119
133
|
end
|
@@ -150,4 +164,3 @@ class Chef
|
|
150
164
|
|
151
165
|
end
|
152
166
|
end
|
153
|
-
|
data/lib/chef/data_bag_item.rb
CHANGED
@@ -112,13 +112,13 @@ class Chef
|
|
112
112
|
# Serialize this object as a hash
|
113
113
|
def to_json(*a)
|
114
114
|
result = {
|
115
|
-
"name"
|
115
|
+
"name" => object_name,
|
116
116
|
"json_class" => self.class.name,
|
117
|
-
"chef_type"
|
118
|
-
"data_bag"
|
119
|
-
"raw_data"
|
117
|
+
"chef_type" => "data_bag_item",
|
118
|
+
"data_bag" => data_bag,
|
119
|
+
"raw_data" => raw_data
|
120
120
|
}
|
121
|
-
|
121
|
+
Chef::JSONCompat.to_json(result, *a)
|
122
122
|
end
|
123
123
|
|
124
124
|
def self.from_hash(h)
|
@@ -210,5 +210,3 @@ class Chef
|
|
210
210
|
|
211
211
|
end
|
212
212
|
end
|
213
|
-
|
214
|
-
|
data/lib/chef/digester.rb
CHANGED
@@ -18,14 +18,11 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
-
require '
|
21
|
+
require 'openssl'
|
22
22
|
|
23
23
|
class Chef
|
24
24
|
class Digester
|
25
|
-
|
26
|
-
def self.instance
|
27
|
-
@instance ||= new
|
28
|
-
end
|
25
|
+
include Singleton
|
29
26
|
|
30
27
|
def self.checksum_for_file(*args)
|
31
28
|
instance.checksum_for_file(*args)
|
@@ -40,7 +37,7 @@ class Chef
|
|
40
37
|
end
|
41
38
|
|
42
39
|
def generate_checksum(file)
|
43
|
-
checksum_file(file, Digest::SHA256.new)
|
40
|
+
checksum_file(file, OpenSSL::Digest::SHA256.new)
|
44
41
|
end
|
45
42
|
|
46
43
|
def self.generate_md5_checksum_for_file(*args)
|
@@ -48,11 +45,11 @@ class Chef
|
|
48
45
|
end
|
49
46
|
|
50
47
|
def generate_md5_checksum_for_file(file)
|
51
|
-
checksum_file(file, Digest::MD5.new)
|
48
|
+
checksum_file(file, OpenSSL::Digest::MD5.new)
|
52
49
|
end
|
53
50
|
|
54
51
|
def generate_md5_checksum(io)
|
55
|
-
checksum_io(io, Digest::MD5.new)
|
52
|
+
checksum_io(io, OpenSSL::Digest::MD5.new)
|
56
53
|
end
|
57
54
|
|
58
55
|
private
|
@@ -70,4 +67,3 @@ class Chef
|
|
70
67
|
|
71
68
|
end
|
72
69
|
end
|
73
|
-
|
data/lib/chef/dsl/recipe.rb
CHANGED
@@ -85,6 +85,20 @@ class Chef
|
|
85
85
|
|
86
86
|
resource = build_resource(type, name, created_at, &resource_attrs_block)
|
87
87
|
|
88
|
+
# Some resources (freebsd_package) can be invoked with multiple names
|
89
|
+
# (package || freebsd_package).
|
90
|
+
# https://github.com/opscode/chef/issues/1773
|
91
|
+
# For these resources we want to make sure
|
92
|
+
# their key in resource collection is same as the name they are declared
|
93
|
+
# as. Since this might be a breaking change for resources that define
|
94
|
+
# customer to_s methods, we are working around the issue by letting
|
95
|
+
# resources know of their created_as_type until this issue is fixed in
|
96
|
+
# Chef 12:
|
97
|
+
# https://github.com/opscode/chef/issues/1817
|
98
|
+
if resource.respond_to?(:created_as_type=)
|
99
|
+
resource.created_as_type = type
|
100
|
+
end
|
101
|
+
|
88
102
|
run_context.resource_collection.insert(resource)
|
89
103
|
resource
|
90
104
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
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 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format'
|
20
|
+
require 'chef/encrypted_data_bag_item/unsupported_cipher'
|
21
|
+
|
22
|
+
class Chef::EncryptedDataBagItem
|
23
|
+
|
24
|
+
class EncryptedDataBagRequirementsFailure < StandardError
|
25
|
+
end
|
26
|
+
|
27
|
+
module Assertions
|
28
|
+
|
29
|
+
def assert_format_version_acceptable!(format_version)
|
30
|
+
unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version]
|
31
|
+
raise UnacceptableEncryptedDataBagItemFormat,
|
32
|
+
"The encrypted data bag item has format version `#{format_version}', " +
|
33
|
+
"but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_valid_cipher!(requested_cipher, algorithm)
|
38
|
+
# In the future, chef may support configurable ciphers. For now, only
|
39
|
+
# aes-256-cbc and aes-256-gcm are supported.
|
40
|
+
unless requested_cipher == algorithm
|
41
|
+
raise UnsupportedCipher,
|
42
|
+
"Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}', '#{AEAD_ALGORITHM}']"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def assert_aead_requirements_met!(algorithm)
|
47
|
+
unless OpenSSL::Cipher.method_defined?(:auth_data=)
|
48
|
+
raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires Ruby >= 1.9"
|
49
|
+
end
|
50
|
+
unless OpenSSL::Cipher.ciphers.include?(algorithm)
|
51
|
+
raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires an OpenSSL version with \"#{algorithm}\" algorithm support"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -17,15 +17,14 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'yaml'
|
20
|
-
require '
|
20
|
+
require 'chef/json_compat'
|
21
21
|
require 'openssl'
|
22
22
|
require 'base64'
|
23
23
|
require 'digest/sha2'
|
24
24
|
require 'chef/encrypted_data_bag_item'
|
25
25
|
require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
|
26
|
-
require 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format'
|
27
26
|
require 'chef/encrypted_data_bag_item/decryption_failure'
|
28
|
-
require 'chef/encrypted_data_bag_item/
|
27
|
+
require 'chef/encrypted_data_bag_item/assertions'
|
29
28
|
|
30
29
|
class Chef::EncryptedDataBagItem
|
31
30
|
|
@@ -37,6 +36,7 @@ class Chef::EncryptedDataBagItem
|
|
37
36
|
# to create an instance of the appropriate strategy for the given encrypted
|
38
37
|
# data bag value.
|
39
38
|
module Decryptor
|
39
|
+
extend Chef::EncryptedDataBagItem::Assertions
|
40
40
|
|
41
41
|
# Detects the encrypted data bag item format version and instantiates a
|
42
42
|
# decryptor object for that version. Call #for_decrypted_item on the
|
@@ -45,6 +45,8 @@ class Chef::EncryptedDataBagItem
|
|
45
45
|
format_version = format_version_of(encrypted_value)
|
46
46
|
assert_format_version_acceptable!(format_version)
|
47
47
|
case format_version
|
48
|
+
when 3
|
49
|
+
Version3Decryptor.new(encrypted_value, key)
|
48
50
|
when 2
|
49
51
|
Version2Decryptor.new(encrypted_value, key)
|
50
52
|
when 1
|
@@ -65,15 +67,8 @@ class Chef::EncryptedDataBagItem
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
def self.assert_format_version_acceptable!(format_version)
|
69
|
-
unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version]
|
70
|
-
raise UnacceptableEncryptedDataBagItemFormat,
|
71
|
-
"The encrypted data bag item has format version `#{format_version}', " +
|
72
|
-
"but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
70
|
class Version0Decryptor
|
71
|
+
include Chef::EncryptedDataBagItem::Assertions
|
77
72
|
|
78
73
|
attr_reader :encrypted_data
|
79
74
|
attr_reader :key
|
@@ -83,6 +78,11 @@ class Chef::EncryptedDataBagItem
|
|
83
78
|
@key = key
|
84
79
|
end
|
85
80
|
|
81
|
+
# Returns the used decryption algorithm
|
82
|
+
def algorithm
|
83
|
+
ALGORITHM
|
84
|
+
end
|
85
|
+
|
86
86
|
def for_decrypted_item
|
87
87
|
YAML.load(decrypted_data)
|
88
88
|
end
|
@@ -102,7 +102,7 @@ class Chef::EncryptedDataBagItem
|
|
102
102
|
|
103
103
|
def openssl_decryptor
|
104
104
|
@openssl_decryptor ||= begin
|
105
|
-
d = OpenSSL::Cipher
|
105
|
+
d = OpenSSL::Cipher.new(algorithm)
|
106
106
|
d.decrypt
|
107
107
|
d.pkcs5_keyivgen(key)
|
108
108
|
d
|
@@ -110,7 +110,7 @@ class Chef::EncryptedDataBagItem
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
class Version1Decryptor
|
113
|
+
class Version1Decryptor < Version0Decryptor
|
114
114
|
|
115
115
|
attr_reader :encrypted_data
|
116
116
|
attr_reader :key
|
@@ -121,8 +121,8 @@ class Chef::EncryptedDataBagItem
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def for_decrypted_item
|
124
|
-
|
125
|
-
rescue
|
124
|
+
Chef::JSONCompat.parse(decrypted_data)["json_wrapper"]
|
125
|
+
rescue Chef::Exceptions::JSON::ParseError
|
126
126
|
# convert to a DecryptionFailure error because the most likely scenario
|
127
127
|
# here is that the decryption step was unsuccessful but returned bad
|
128
128
|
# data rather than raising an error.
|
@@ -148,24 +148,16 @@ class Chef::EncryptedDataBagItem
|
|
148
148
|
|
149
149
|
def openssl_decryptor
|
150
150
|
@openssl_decryptor ||= begin
|
151
|
-
assert_valid_cipher!
|
152
|
-
d = OpenSSL::Cipher
|
151
|
+
assert_valid_cipher!(@encrypted_data["cipher"], algorithm)
|
152
|
+
d = OpenSSL::Cipher.new(algorithm)
|
153
153
|
d.decrypt
|
154
|
-
|
154
|
+
# We must set key before iv: https://bugs.ruby-lang.org/issues/8221
|
155
|
+
d.key = OpenSSL::Digest::SHA256.digest(key)
|
155
156
|
d.iv = iv
|
156
157
|
d
|
157
158
|
end
|
158
159
|
end
|
159
160
|
|
160
|
-
def assert_valid_cipher!
|
161
|
-
# In the future, chef may support configurable ciphers. For now, only
|
162
|
-
# aes-256-cbc is supported.
|
163
|
-
requested_cipher = @encrypted_data["cipher"]
|
164
|
-
unless requested_cipher == ALGORITHM
|
165
|
-
raise UnsupportedCipher,
|
166
|
-
"Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}']"
|
167
|
-
end
|
168
|
-
end
|
169
161
|
end
|
170
162
|
|
171
163
|
class Version2Decryptor < Version1Decryptor
|
@@ -176,7 +168,7 @@ class Chef::EncryptedDataBagItem
|
|
176
168
|
end
|
177
169
|
|
178
170
|
def validate_hmac!
|
179
|
-
digest = OpenSSL::Digest
|
171
|
+
digest = OpenSSL::Digest.new("sha256")
|
180
172
|
raw_hmac = OpenSSL::HMAC.digest(digest, key, @encrypted_data["encrypted_data"])
|
181
173
|
|
182
174
|
if candidate_hmac_matches?(raw_hmac)
|
@@ -197,5 +189,37 @@ class Chef::EncryptedDataBagItem
|
|
197
189
|
valid == 0
|
198
190
|
end
|
199
191
|
end
|
192
|
+
|
193
|
+
class Version3Decryptor < Version1Decryptor
|
194
|
+
|
195
|
+
def initialize(encrypted_data, key)
|
196
|
+
super
|
197
|
+
assert_aead_requirements_met!(algorithm)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns the used decryption algorithm
|
201
|
+
def algorithm
|
202
|
+
AEAD_ALGORITHM
|
203
|
+
end
|
204
|
+
|
205
|
+
def auth_tag
|
206
|
+
auth_tag_b64 = @encrypted_data["auth_tag"]
|
207
|
+
if auth_tag_b64.nil?
|
208
|
+
raise DecryptionFailure, "Error decrypting data bag value: invalid authentication tag. Most likely the data is corrupted"
|
209
|
+
end
|
210
|
+
Base64.decode64(auth_tag_b64)
|
211
|
+
end
|
212
|
+
|
213
|
+
def openssl_decryptor
|
214
|
+
@openssl_decryptor ||= begin
|
215
|
+
d = super
|
216
|
+
d.auth_tag = auth_tag
|
217
|
+
d.auth_data = ''
|
218
|
+
d
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
200
224
|
end
|
201
225
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
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
|
+
class Chef::EncryptedDataBagItem
|
20
|
+
|
21
|
+
class EncryptedDataBagRequirementsFailure < StandardError
|
22
|
+
end
|
23
|
+
|
24
|
+
module Assertions
|
25
|
+
|
26
|
+
def assert_requirements_met!
|
27
|
+
unless OpenSSL::Cipher.method_defined?(:auth_data=)
|
28
|
+
raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires Ruby >= 1.9"
|
29
|
+
end
|
30
|
+
unless OpenSSL::Cipher.ciphers.include?(algorithm)
|
31
|
+
raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires an OpenSSL version with \"#{algorithm}\" algorithm support"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
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
|
+
class Chef::EncryptedDataBagItem
|
20
|
+
class EncryptionFailure < StandardError
|
21
|
+
end
|
22
|
+
end
|