cheffish 1.4.1 → 1.4.2
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/LICENSE +201 -201
- data/README.md +120 -120
- data/Rakefile +23 -23
- data/lib/chef/provider/chef_acl.rb +439 -439
- data/lib/chef/provider/chef_client.rb +53 -53
- data/lib/chef/provider/chef_container.rb +55 -55
- data/lib/chef/provider/chef_data_bag.rb +55 -55
- data/lib/chef/provider/chef_data_bag_item.rb +278 -278
- data/lib/chef/provider/chef_environment.rb +83 -83
- data/lib/chef/provider/chef_group.rb +83 -83
- data/lib/chef/provider/chef_mirror.rb +169 -169
- data/lib/chef/provider/chef_node.rb +87 -87
- data/lib/chef/provider/chef_organization.rb +155 -155
- data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
- data/lib/chef/provider/chef_role.rb +84 -84
- data/lib/chef/provider/chef_user.rb +59 -59
- data/lib/chef/provider/private_key.rb +225 -225
- data/lib/chef/provider/public_key.rb +88 -88
- data/lib/chef/resource/chef_acl.rb +69 -69
- data/lib/chef/resource/chef_client.rb +48 -48
- data/lib/chef/resource/chef_container.rb +22 -22
- data/lib/chef/resource/chef_data_bag.rb +22 -22
- data/lib/chef/resource/chef_data_bag_item.rb +121 -121
- data/lib/chef/resource/chef_environment.rb +77 -77
- data/lib/chef/resource/chef_group.rb +53 -53
- data/lib/chef/resource/chef_mirror.rb +52 -52
- data/lib/chef/resource/chef_node.rb +22 -22
- data/lib/chef/resource/chef_organization.rb +69 -69
- data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
- data/lib/chef/resource/chef_role.rb +110 -110
- data/lib/chef/resource/chef_user.rb +56 -56
- data/lib/chef/resource/private_key.rb +48 -48
- data/lib/chef/resource/public_key.rb +25 -25
- data/lib/cheffish/actor_provider_base.rb +131 -131
- data/lib/cheffish/basic_chef_client.rb +184 -184
- data/lib/cheffish/chef_provider_base.rb +246 -246
- data/lib/cheffish/chef_run.rb +162 -162
- data/lib/cheffish/chef_run_data.rb +19 -19
- data/lib/cheffish/chef_run_listener.rb +30 -30
- data/lib/cheffish/key_formatter.rb +113 -113
- data/lib/cheffish/merged_config.rb +94 -94
- data/lib/cheffish/recipe_dsl.rb +157 -157
- data/lib/cheffish/rspec/chef_run_support.rb +83 -83
- data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
- data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
- data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
- data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
- data/lib/cheffish/rspec/matchers.rb +4 -4
- data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -59
- data/lib/cheffish/rspec/repository_support.rb +108 -108
- data/lib/cheffish/rspec.rb +8 -8
- data/lib/cheffish/server_api.rb +52 -52
- data/lib/cheffish/version.rb +3 -3
- data/lib/cheffish/with_pattern.rb +21 -21
- data/lib/cheffish.rb +235 -235
- data/spec/functional/fingerprint_spec.rb +64 -64
- data/spec/functional/merged_config_spec.rb +19 -19
- data/spec/functional/server_api_spec.rb +13 -13
- data/spec/integration/chef_acl_spec.rb +879 -879
- data/spec/integration/chef_client_spec.rb +105 -105
- data/spec/integration/chef_container_spec.rb +33 -33
- data/spec/integration/chef_group_spec.rb +309 -309
- data/spec/integration/chef_mirror_spec.rb +491 -491
- data/spec/integration/chef_node_spec.rb +786 -786
- data/spec/integration/chef_organization_spec.rb +226 -226
- data/spec/integration/chef_role_spec.rb +78 -78
- data/spec/integration/chef_user_spec.rb +85 -85
- data/spec/integration/private_key_spec.rb +399 -399
- data/spec/integration/recipe_dsl_spec.rb +28 -28
- data/spec/integration/rspec/converge_spec.rb +183 -183
- data/spec/support/key_support.rb +29 -29
- data/spec/support/spec_support.rb +15 -15
- data/spec/unit/get_private_key_spec.rb +131 -131
- data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
- metadata +3 -2
@@ -1,225 +1,225 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'openssl'
|
3
|
-
require 'cheffish/key_formatter'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class PrivateKey < Chef::Provider::LWRPBase
|
8
|
-
provides :private_key
|
9
|
-
|
10
|
-
action :create do
|
11
|
-
create_key(false, :create)
|
12
|
-
end
|
13
|
-
|
14
|
-
action :regenerate do
|
15
|
-
create_key(true, :regenerate)
|
16
|
-
end
|
17
|
-
|
18
|
-
action :delete do
|
19
|
-
if current_resource.path
|
20
|
-
converge_by "delete private key #{new_path}" do
|
21
|
-
::File.unlink(new_path)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
use_inline_resources
|
27
|
-
|
28
|
-
def whyrun_supported?
|
29
|
-
true
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_key(regenerate, action)
|
33
|
-
if @should_create_directory
|
34
|
-
Cheffish.inline_resource(self, action) do
|
35
|
-
directory run_context.config[:private_key_write_path]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
final_private_key = nil
|
40
|
-
if new_source_key
|
41
|
-
#
|
42
|
-
# Create private key from source
|
43
|
-
#
|
44
|
-
desired_output = encode_private_key(new_source_key)
|
45
|
-
if current_resource.path == :none || desired_output != IO.read(new_path)
|
46
|
-
converge_by "reformat key at #{new_resource.source_key_path} to #{new_resource.format} private key #{new_path} (#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})" do
|
47
|
-
IO.write(new_path, desired_output)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
final_private_key = new_source_key
|
52
|
-
|
53
|
-
else
|
54
|
-
#
|
55
|
-
# Generate a new key
|
56
|
-
#
|
57
|
-
if current_resource.action == [ :delete ] || regenerate ||
|
58
|
-
(new_resource.regenerate_if_different &&
|
59
|
-
(!current_private_key ||
|
60
|
-
current_resource.size != new_resource.size ||
|
61
|
-
current_resource.type != new_resource.type))
|
62
|
-
|
63
|
-
case new_resource.type
|
64
|
-
when :rsa
|
65
|
-
if new_resource.exponent
|
66
|
-
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size, new_resource.exponent)
|
67
|
-
else
|
68
|
-
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size)
|
69
|
-
end
|
70
|
-
when :dsa
|
71
|
-
final_private_key = OpenSSL::PKey::DSA.generate(new_resource.size)
|
72
|
-
end
|
73
|
-
|
74
|
-
generated_key = true
|
75
|
-
elsif !current_private_key
|
76
|
-
raise "Could not read private key from #{current_resource.path}: missing pass phrase?"
|
77
|
-
else
|
78
|
-
final_private_key = current_private_key
|
79
|
-
generated_key = false
|
80
|
-
end
|
81
|
-
|
82
|
-
if generated_key
|
83
|
-
generated_description = " (#{new_resource.size} bits#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})"
|
84
|
-
|
85
|
-
if new_path != :none
|
86
|
-
action = current_resource.path == :none ? 'create' : 'overwrite'
|
87
|
-
converge_by "#{action} #{new_resource.type} private key #{new_path}#{generated_description}" do
|
88
|
-
write_private_key(final_private_key)
|
89
|
-
end
|
90
|
-
else
|
91
|
-
converge_by "generate private key#{generated_description}" do
|
92
|
-
end
|
93
|
-
end
|
94
|
-
else
|
95
|
-
# Warn if existing key has different characteristics than expected
|
96
|
-
if current_resource.size != new_resource.size
|
97
|
-
Chef::Log.warn("Mismatched key size! #{current_resource.path} is #{current_resource.size} bytes, desired is #{new_resource.size} bytes. Use action :regenerate to force key regeneration.")
|
98
|
-
elsif current_resource.type != new_resource.type
|
99
|
-
Chef::Log.warn("Mismatched key type! #{current_resource.path} is #{current_resource.type}, desired is #{new_resource.type} bytes. Use action :regenerate to force key regeneration.")
|
100
|
-
end
|
101
|
-
|
102
|
-
if current_resource.format != new_resource.format
|
103
|
-
converge_by "change format of #{new_resource.type} private key #{new_path} from #{current_resource.format} to #{new_resource.format}" do
|
104
|
-
write_private_key(current_private_key)
|
105
|
-
end
|
106
|
-
elsif (@current_file_mode & 0077) != 0
|
107
|
-
new_mode = @current_file_mode & 07700
|
108
|
-
converge_by "change mode of private key #{new_path} to #{new_mode.to_s(8)}" do
|
109
|
-
::File.chmod(new_mode, new_path)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
if new_resource.public_key_path
|
116
|
-
public_key_path = new_resource.public_key_path
|
117
|
-
public_key_format = new_resource.public_key_format
|
118
|
-
Cheffish.inline_resource(self, action) do
|
119
|
-
public_key public_key_path do
|
120
|
-
source_key final_private_key
|
121
|
-
format public_key_format
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
if new_resource.after
|
127
|
-
new_resource.after.call(new_resource, final_private_key)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def encode_private_key(key)
|
132
|
-
key_format = {}
|
133
|
-
key_format[:format] = new_resource.format if new_resource.format
|
134
|
-
key_format[:pass_phrase] = new_resource.pass_phrase if new_resource.pass_phrase
|
135
|
-
key_format[:cipher] = new_resource.cipher if new_resource.cipher
|
136
|
-
Cheffish::KeyFormatter.encode(key, key_format)
|
137
|
-
end
|
138
|
-
|
139
|
-
def write_private_key(key)
|
140
|
-
::File.open(new_path, 'w') do |file|
|
141
|
-
file.chmod(0600)
|
142
|
-
file.write(encode_private_key(key))
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def new_source_key
|
147
|
-
@new_source_key ||= begin
|
148
|
-
if new_resource.source_key.is_a?(String)
|
149
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
150
|
-
source_key
|
151
|
-
elsif new_resource.source_key
|
152
|
-
new_resource.source_key
|
153
|
-
elsif new_resource.source_key_path
|
154
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
155
|
-
source_key
|
156
|
-
else
|
157
|
-
nil
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
attr_reader :current_private_key
|
163
|
-
|
164
|
-
def new_path
|
165
|
-
new_key_with_path[1]
|
166
|
-
end
|
167
|
-
|
168
|
-
def new_key_with_path
|
169
|
-
path = new_resource.path
|
170
|
-
if path.is_a?(Symbol)
|
171
|
-
return [ nil, path ]
|
172
|
-
elsif Pathname.new(path).relative?
|
173
|
-
private_key, private_key_path = Cheffish.get_private_key_with_path(path, run_context.config)
|
174
|
-
if private_key
|
175
|
-
return [ private_key, (private_key_path || :none) ]
|
176
|
-
elsif run_context.config[:private_key_write_path]
|
177
|
-
@should_create_directory = true
|
178
|
-
path = ::File.join(run_context.config[:private_key_write_path], path)
|
179
|
-
return [ nil, path ]
|
180
|
-
else
|
181
|
-
raise "Could not find key #{path} and Chef::Config.private_key_write_path is not set."
|
182
|
-
end
|
183
|
-
elsif ::File.exist?(path)
|
184
|
-
return [ IO.read(path), path ]
|
185
|
-
else
|
186
|
-
return [ nil, path ]
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def load_current_resource
|
191
|
-
resource = Chef::Resource::PrivateKey.new(new_resource.name, run_context)
|
192
|
-
|
193
|
-
new_key, new_path = new_key_with_path
|
194
|
-
if new_path != :none && ::File.exist?(new_path)
|
195
|
-
resource.path new_path
|
196
|
-
@current_file_mode = ::File.stat(new_path).mode
|
197
|
-
else
|
198
|
-
resource.path :none
|
199
|
-
end
|
200
|
-
|
201
|
-
if new_key
|
202
|
-
begin
|
203
|
-
key, key_format = Cheffish::KeyFormatter.decode(new_key, new_resource.pass_phrase, new_path)
|
204
|
-
if key
|
205
|
-
@current_private_key = key
|
206
|
-
resource.format key_format[:format]
|
207
|
-
resource.type key_format[:type]
|
208
|
-
resource.size key_format[:size]
|
209
|
-
resource.exponent key_format[:exponent]
|
210
|
-
resource.pass_phrase key_format[:pass_phrase]
|
211
|
-
resource.cipher key_format[:cipher]
|
212
|
-
end
|
213
|
-
rescue
|
214
|
-
# If there's an error reading, we assume format and type are wrong and don't futz with them
|
215
|
-
Chef::Log.warn("Error reading #{new_path}: #{$!}")
|
216
|
-
end
|
217
|
-
else
|
218
|
-
resource.action :delete
|
219
|
-
end
|
220
|
-
|
221
|
-
@current_resource = resource
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'openssl'
|
3
|
+
require 'cheffish/key_formatter'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Provider
|
7
|
+
class PrivateKey < Chef::Provider::LWRPBase
|
8
|
+
provides :private_key
|
9
|
+
|
10
|
+
action :create do
|
11
|
+
create_key(false, :create)
|
12
|
+
end
|
13
|
+
|
14
|
+
action :regenerate do
|
15
|
+
create_key(true, :regenerate)
|
16
|
+
end
|
17
|
+
|
18
|
+
action :delete do
|
19
|
+
if current_resource.path
|
20
|
+
converge_by "delete private key #{new_path}" do
|
21
|
+
::File.unlink(new_path)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
use_inline_resources
|
27
|
+
|
28
|
+
def whyrun_supported?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_key(regenerate, action)
|
33
|
+
if @should_create_directory
|
34
|
+
Cheffish.inline_resource(self, action) do
|
35
|
+
directory run_context.config[:private_key_write_path]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
final_private_key = nil
|
40
|
+
if new_source_key
|
41
|
+
#
|
42
|
+
# Create private key from source
|
43
|
+
#
|
44
|
+
desired_output = encode_private_key(new_source_key)
|
45
|
+
if current_resource.path == :none || desired_output != IO.read(new_path)
|
46
|
+
converge_by "reformat key at #{new_resource.source_key_path} to #{new_resource.format} private key #{new_path} (#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})" do
|
47
|
+
IO.write(new_path, desired_output)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
final_private_key = new_source_key
|
52
|
+
|
53
|
+
else
|
54
|
+
#
|
55
|
+
# Generate a new key
|
56
|
+
#
|
57
|
+
if current_resource.action == [ :delete ] || regenerate ||
|
58
|
+
(new_resource.regenerate_if_different &&
|
59
|
+
(!current_private_key ||
|
60
|
+
current_resource.size != new_resource.size ||
|
61
|
+
current_resource.type != new_resource.type))
|
62
|
+
|
63
|
+
case new_resource.type
|
64
|
+
when :rsa
|
65
|
+
if new_resource.exponent
|
66
|
+
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size, new_resource.exponent)
|
67
|
+
else
|
68
|
+
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size)
|
69
|
+
end
|
70
|
+
when :dsa
|
71
|
+
final_private_key = OpenSSL::PKey::DSA.generate(new_resource.size)
|
72
|
+
end
|
73
|
+
|
74
|
+
generated_key = true
|
75
|
+
elsif !current_private_key
|
76
|
+
raise "Could not read private key from #{current_resource.path}: missing pass phrase?"
|
77
|
+
else
|
78
|
+
final_private_key = current_private_key
|
79
|
+
generated_key = false
|
80
|
+
end
|
81
|
+
|
82
|
+
if generated_key
|
83
|
+
generated_description = " (#{new_resource.size} bits#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})"
|
84
|
+
|
85
|
+
if new_path != :none
|
86
|
+
action = current_resource.path == :none ? 'create' : 'overwrite'
|
87
|
+
converge_by "#{action} #{new_resource.type} private key #{new_path}#{generated_description}" do
|
88
|
+
write_private_key(final_private_key)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
converge_by "generate private key#{generated_description}" do
|
92
|
+
end
|
93
|
+
end
|
94
|
+
else
|
95
|
+
# Warn if existing key has different characteristics than expected
|
96
|
+
if current_resource.size != new_resource.size
|
97
|
+
Chef::Log.warn("Mismatched key size! #{current_resource.path} is #{current_resource.size} bytes, desired is #{new_resource.size} bytes. Use action :regenerate to force key regeneration.")
|
98
|
+
elsif current_resource.type != new_resource.type
|
99
|
+
Chef::Log.warn("Mismatched key type! #{current_resource.path} is #{current_resource.type}, desired is #{new_resource.type} bytes. Use action :regenerate to force key regeneration.")
|
100
|
+
end
|
101
|
+
|
102
|
+
if current_resource.format != new_resource.format
|
103
|
+
converge_by "change format of #{new_resource.type} private key #{new_path} from #{current_resource.format} to #{new_resource.format}" do
|
104
|
+
write_private_key(current_private_key)
|
105
|
+
end
|
106
|
+
elsif (@current_file_mode & 0077) != 0
|
107
|
+
new_mode = @current_file_mode & 07700
|
108
|
+
converge_by "change mode of private key #{new_path} to #{new_mode.to_s(8)}" do
|
109
|
+
::File.chmod(new_mode, new_path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
if new_resource.public_key_path
|
116
|
+
public_key_path = new_resource.public_key_path
|
117
|
+
public_key_format = new_resource.public_key_format
|
118
|
+
Cheffish.inline_resource(self, action) do
|
119
|
+
public_key public_key_path do
|
120
|
+
source_key final_private_key
|
121
|
+
format public_key_format
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if new_resource.after
|
127
|
+
new_resource.after.call(new_resource, final_private_key)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def encode_private_key(key)
|
132
|
+
key_format = {}
|
133
|
+
key_format[:format] = new_resource.format if new_resource.format
|
134
|
+
key_format[:pass_phrase] = new_resource.pass_phrase if new_resource.pass_phrase
|
135
|
+
key_format[:cipher] = new_resource.cipher if new_resource.cipher
|
136
|
+
Cheffish::KeyFormatter.encode(key, key_format)
|
137
|
+
end
|
138
|
+
|
139
|
+
def write_private_key(key)
|
140
|
+
::File.open(new_path, 'w') do |file|
|
141
|
+
file.chmod(0600)
|
142
|
+
file.write(encode_private_key(key))
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def new_source_key
|
147
|
+
@new_source_key ||= begin
|
148
|
+
if new_resource.source_key.is_a?(String)
|
149
|
+
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
150
|
+
source_key
|
151
|
+
elsif new_resource.source_key
|
152
|
+
new_resource.source_key
|
153
|
+
elsif new_resource.source_key_path
|
154
|
+
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
155
|
+
source_key
|
156
|
+
else
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
attr_reader :current_private_key
|
163
|
+
|
164
|
+
def new_path
|
165
|
+
new_key_with_path[1]
|
166
|
+
end
|
167
|
+
|
168
|
+
def new_key_with_path
|
169
|
+
path = new_resource.path
|
170
|
+
if path.is_a?(Symbol)
|
171
|
+
return [ nil, path ]
|
172
|
+
elsif Pathname.new(path).relative?
|
173
|
+
private_key, private_key_path = Cheffish.get_private_key_with_path(path, run_context.config)
|
174
|
+
if private_key
|
175
|
+
return [ private_key, (private_key_path || :none) ]
|
176
|
+
elsif run_context.config[:private_key_write_path]
|
177
|
+
@should_create_directory = true
|
178
|
+
path = ::File.join(run_context.config[:private_key_write_path], path)
|
179
|
+
return [ nil, path ]
|
180
|
+
else
|
181
|
+
raise "Could not find key #{path} and Chef::Config.private_key_write_path is not set."
|
182
|
+
end
|
183
|
+
elsif ::File.exist?(path)
|
184
|
+
return [ IO.read(path), path ]
|
185
|
+
else
|
186
|
+
return [ nil, path ]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def load_current_resource
|
191
|
+
resource = Chef::Resource::PrivateKey.new(new_resource.name, run_context)
|
192
|
+
|
193
|
+
new_key, new_path = new_key_with_path
|
194
|
+
if new_path != :none && ::File.exist?(new_path)
|
195
|
+
resource.path new_path
|
196
|
+
@current_file_mode = ::File.stat(new_path).mode
|
197
|
+
else
|
198
|
+
resource.path :none
|
199
|
+
end
|
200
|
+
|
201
|
+
if new_key
|
202
|
+
begin
|
203
|
+
key, key_format = Cheffish::KeyFormatter.decode(new_key, new_resource.pass_phrase, new_path)
|
204
|
+
if key
|
205
|
+
@current_private_key = key
|
206
|
+
resource.format key_format[:format]
|
207
|
+
resource.type key_format[:type]
|
208
|
+
resource.size key_format[:size]
|
209
|
+
resource.exponent key_format[:exponent]
|
210
|
+
resource.pass_phrase key_format[:pass_phrase]
|
211
|
+
resource.cipher key_format[:cipher]
|
212
|
+
end
|
213
|
+
rescue
|
214
|
+
# If there's an error reading, we assume format and type are wrong and don't futz with them
|
215
|
+
Chef::Log.warn("Error reading #{new_path}: #{$!}")
|
216
|
+
end
|
217
|
+
else
|
218
|
+
resource.action :delete
|
219
|
+
end
|
220
|
+
|
221
|
+
@current_resource = resource
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -1,88 +1,88 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'openssl'
|
3
|
-
require 'cheffish/key_formatter'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class PublicKey < Chef::Provider::LWRPBase
|
8
|
-
provides :public_key
|
9
|
-
|
10
|
-
action :create do
|
11
|
-
if !new_source_key
|
12
|
-
raise "No source key specified"
|
13
|
-
end
|
14
|
-
desired_output = encode_public_key(new_source_key)
|
15
|
-
if Array(current_resource.action) == [ :delete ] || desired_output != IO.read(new_resource.path)
|
16
|
-
converge_by "write #{new_resource.format} public key #{new_resource.path} from #{new_source_key_publicity} key #{new_resource.source_key_path}" do
|
17
|
-
IO.write(new_resource.path, desired_output)
|
18
|
-
# TODO permissions on file?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
action :delete do
|
24
|
-
if Array(current_resource.action) == [ :create ]
|
25
|
-
converge_by "delete public key #{new_resource.path}" do
|
26
|
-
::File.unlink(new_resource.path)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def whyrun_supported?
|
32
|
-
true
|
33
|
-
end
|
34
|
-
|
35
|
-
def encode_public_key(key)
|
36
|
-
key_format = {}
|
37
|
-
key_format[:format] = new_resource.format if new_resource.format
|
38
|
-
Cheffish::KeyFormatter.encode(key, key_format)
|
39
|
-
end
|
40
|
-
|
41
|
-
attr_reader :current_public_key
|
42
|
-
attr_reader :new_source_key_publicity
|
43
|
-
|
44
|
-
def new_source_key
|
45
|
-
@new_source_key ||= begin
|
46
|
-
if new_resource.source_key.is_a?(String)
|
47
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
48
|
-
elsif new_resource.source_key
|
49
|
-
source_key = new_resource.source_key
|
50
|
-
elsif new_resource.source_key_path
|
51
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
52
|
-
else
|
53
|
-
return nil
|
54
|
-
end
|
55
|
-
|
56
|
-
if source_key.private?
|
57
|
-
@new_source_key_publicity = 'private'
|
58
|
-
source_key.public_key
|
59
|
-
else
|
60
|
-
@new_source_key_publicity = 'public'
|
61
|
-
source_key
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def load_current_resource
|
67
|
-
if ::File.exist?(new_resource.path)
|
68
|
-
resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
69
|
-
begin
|
70
|
-
key, key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.path), nil, new_resource.path)
|
71
|
-
if key
|
72
|
-
@current_public_key = key
|
73
|
-
resource.format key_format[:format]
|
74
|
-
end
|
75
|
-
rescue
|
76
|
-
# If there is an error reading we assume format and such is broken
|
77
|
-
end
|
78
|
-
|
79
|
-
@current_resource = resource
|
80
|
-
else
|
81
|
-
not_found_resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
82
|
-
not_found_resource.action :delete
|
83
|
-
@current_resource = not_found_resource
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'openssl'
|
3
|
+
require 'cheffish/key_formatter'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Provider
|
7
|
+
class PublicKey < Chef::Provider::LWRPBase
|
8
|
+
provides :public_key
|
9
|
+
|
10
|
+
action :create do
|
11
|
+
if !new_source_key
|
12
|
+
raise "No source key specified"
|
13
|
+
end
|
14
|
+
desired_output = encode_public_key(new_source_key)
|
15
|
+
if Array(current_resource.action) == [ :delete ] || desired_output != IO.read(new_resource.path)
|
16
|
+
converge_by "write #{new_resource.format} public key #{new_resource.path} from #{new_source_key_publicity} key #{new_resource.source_key_path}" do
|
17
|
+
IO.write(new_resource.path, desired_output)
|
18
|
+
# TODO permissions on file?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
action :delete do
|
24
|
+
if Array(current_resource.action) == [ :create ]
|
25
|
+
converge_by "delete public key #{new_resource.path}" do
|
26
|
+
::File.unlink(new_resource.path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def whyrun_supported?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def encode_public_key(key)
|
36
|
+
key_format = {}
|
37
|
+
key_format[:format] = new_resource.format if new_resource.format
|
38
|
+
Cheffish::KeyFormatter.encode(key, key_format)
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :current_public_key
|
42
|
+
attr_reader :new_source_key_publicity
|
43
|
+
|
44
|
+
def new_source_key
|
45
|
+
@new_source_key ||= begin
|
46
|
+
if new_resource.source_key.is_a?(String)
|
47
|
+
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
48
|
+
elsif new_resource.source_key
|
49
|
+
source_key = new_resource.source_key
|
50
|
+
elsif new_resource.source_key_path
|
51
|
+
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
52
|
+
else
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
|
56
|
+
if source_key.private?
|
57
|
+
@new_source_key_publicity = 'private'
|
58
|
+
source_key.public_key
|
59
|
+
else
|
60
|
+
@new_source_key_publicity = 'public'
|
61
|
+
source_key
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_current_resource
|
67
|
+
if ::File.exist?(new_resource.path)
|
68
|
+
resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
69
|
+
begin
|
70
|
+
key, key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.path), nil, new_resource.path)
|
71
|
+
if key
|
72
|
+
@current_public_key = key
|
73
|
+
resource.format key_format[:format]
|
74
|
+
end
|
75
|
+
rescue
|
76
|
+
# If there is an error reading we assume format and such is broken
|
77
|
+
end
|
78
|
+
|
79
|
+
@current_resource = resource
|
80
|
+
else
|
81
|
+
not_found_resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
82
|
+
not_found_resource.action :delete
|
83
|
+
@current_resource = not_found_resource
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|