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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +120 -120
  4. data/Rakefile +23 -23
  5. data/lib/chef/provider/chef_acl.rb +439 -439
  6. data/lib/chef/provider/chef_client.rb +53 -53
  7. data/lib/chef/provider/chef_container.rb +55 -55
  8. data/lib/chef/provider/chef_data_bag.rb +55 -55
  9. data/lib/chef/provider/chef_data_bag_item.rb +278 -278
  10. data/lib/chef/provider/chef_environment.rb +83 -83
  11. data/lib/chef/provider/chef_group.rb +83 -83
  12. data/lib/chef/provider/chef_mirror.rb +169 -169
  13. data/lib/chef/provider/chef_node.rb +87 -87
  14. data/lib/chef/provider/chef_organization.rb +155 -155
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
  16. data/lib/chef/provider/chef_role.rb +84 -84
  17. data/lib/chef/provider/chef_user.rb +59 -59
  18. data/lib/chef/provider/private_key.rb +225 -225
  19. data/lib/chef/provider/public_key.rb +88 -88
  20. data/lib/chef/resource/chef_acl.rb +69 -69
  21. data/lib/chef/resource/chef_client.rb +48 -48
  22. data/lib/chef/resource/chef_container.rb +22 -22
  23. data/lib/chef/resource/chef_data_bag.rb +22 -22
  24. data/lib/chef/resource/chef_data_bag_item.rb +121 -121
  25. data/lib/chef/resource/chef_environment.rb +77 -77
  26. data/lib/chef/resource/chef_group.rb +53 -53
  27. data/lib/chef/resource/chef_mirror.rb +52 -52
  28. data/lib/chef/resource/chef_node.rb +22 -22
  29. data/lib/chef/resource/chef_organization.rb +69 -69
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
  31. data/lib/chef/resource/chef_role.rb +110 -110
  32. data/lib/chef/resource/chef_user.rb +56 -56
  33. data/lib/chef/resource/private_key.rb +48 -48
  34. data/lib/chef/resource/public_key.rb +25 -25
  35. data/lib/cheffish/actor_provider_base.rb +131 -131
  36. data/lib/cheffish/basic_chef_client.rb +184 -184
  37. data/lib/cheffish/chef_provider_base.rb +246 -246
  38. data/lib/cheffish/chef_run.rb +162 -162
  39. data/lib/cheffish/chef_run_data.rb +19 -19
  40. data/lib/cheffish/chef_run_listener.rb +30 -30
  41. data/lib/cheffish/key_formatter.rb +113 -113
  42. data/lib/cheffish/merged_config.rb +94 -94
  43. data/lib/cheffish/recipe_dsl.rb +157 -157
  44. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  45. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  46. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  47. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  48. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  49. data/lib/cheffish/rspec/matchers.rb +4 -4
  50. data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -59
  51. data/lib/cheffish/rspec/repository_support.rb +108 -108
  52. data/lib/cheffish/rspec.rb +8 -8
  53. data/lib/cheffish/server_api.rb +52 -52
  54. data/lib/cheffish/version.rb +3 -3
  55. data/lib/cheffish/with_pattern.rb +21 -21
  56. data/lib/cheffish.rb +235 -235
  57. data/spec/functional/fingerprint_spec.rb +64 -64
  58. data/spec/functional/merged_config_spec.rb +19 -19
  59. data/spec/functional/server_api_spec.rb +13 -13
  60. data/spec/integration/chef_acl_spec.rb +879 -879
  61. data/spec/integration/chef_client_spec.rb +105 -105
  62. data/spec/integration/chef_container_spec.rb +33 -33
  63. data/spec/integration/chef_group_spec.rb +309 -309
  64. data/spec/integration/chef_mirror_spec.rb +491 -491
  65. data/spec/integration/chef_node_spec.rb +786 -786
  66. data/spec/integration/chef_organization_spec.rb +226 -226
  67. data/spec/integration/chef_role_spec.rb +78 -78
  68. data/spec/integration/chef_user_spec.rb +85 -85
  69. data/spec/integration/private_key_spec.rb +399 -399
  70. data/spec/integration/recipe_dsl_spec.rb +28 -28
  71. data/spec/integration/rspec/converge_spec.rb +183 -183
  72. data/spec/support/key_support.rb +29 -29
  73. data/spec/support/spec_support.rb +15 -15
  74. data/spec/unit/get_private_key_spec.rb +131 -131
  75. data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
  76. 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