cheffish 1.4.0 → 1.4.1

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.rb +235 -235
  36. data/lib/cheffish/actor_provider_base.rb +131 -131
  37. data/lib/cheffish/basic_chef_client.rb +184 -184
  38. data/lib/cheffish/chef_provider_base.rb +246 -246
  39. data/lib/cheffish/chef_run.rb +162 -162
  40. data/lib/cheffish/chef_run_data.rb +19 -19
  41. data/lib/cheffish/chef_run_listener.rb +30 -30
  42. data/lib/cheffish/key_formatter.rb +113 -113
  43. data/lib/cheffish/merged_config.rb +94 -94
  44. data/lib/cheffish/recipe_dsl.rb +157 -157
  45. data/lib/cheffish/rspec.rb +8 -8
  46. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  47. data/lib/cheffish/rspec/matchers.rb +4 -4
  48. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  49. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  50. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  51. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  52. data/lib/cheffish/rspec/recipe_run_wrapper.rb +59 -59
  53. data/lib/cheffish/rspec/repository_support.rb +108 -108
  54. data/lib/cheffish/server_api.rb +52 -52
  55. data/lib/cheffish/version.rb +3 -3
  56. data/lib/cheffish/with_pattern.rb +21 -21
  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 -4
@@ -1,85 +1,85 @@
1
- require 'support/spec_support'
2
- require 'cheffish/rspec/chef_run_support'
3
- require 'support/key_support'
4
- require 'chef/resource/chef_user'
5
- require 'chef/provider/chef_user'
6
-
7
- repo_path = Dir.mktmpdir('chef_repo')
8
-
9
- describe Chef::Resource::ChefUser do
10
- extend Cheffish::RSpec::ChefRunSupport
11
-
12
- with_converge do
13
- private_key "#{repo_path}/blah.pem"
14
- end
15
-
16
- when_the_chef_server 'is empty' do
17
- context 'and we run a recipe that creates user "blah"'do
18
- it 'the user gets created' do
19
- expect_recipe {
20
- chef_user 'blah' do
21
- source_key_path "#{repo_path}/blah.pem"
22
- end
23
- }.to have_updated 'chef_user[blah]', :create
24
- user = get('/users/blah')
25
- expect(user['name']).to eq('blah')
26
- key, format = Cheffish::KeyFormatter.decode(user['public_key'])
27
- expect(key).to be_public_key_for("#{repo_path}/blah.pem")
28
- end
29
- end
30
-
31
- context 'and we run a recipe that creates user "blah" with output_key_path' do
32
- with_converge do
33
- chef_user 'blah' do
34
- source_key_path "#{repo_path}/blah.pem"
35
- output_key_path "#{repo_path}/blah.pub"
36
- end
37
- end
38
-
39
- it 'the output public key gets created' do
40
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
41
- expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah.pem")
42
- end
43
- end
44
- end
45
-
46
- when_the_chef_12_server 'is in multi-org mode' do
47
- context 'and chef_server_url is pointed at the top level' do
48
- context 'and we run a recipe that creates user "blah"'do
49
- it 'the user gets created' do
50
- expect_recipe {
51
- chef_user 'blah' do
52
- source_key_path "#{repo_path}/blah.pem"
53
- end
54
- }.to have_updated 'chef_user[blah]', :create
55
- user = get('/users/blah')
56
- expect(user['name']).to eq('blah')
57
- key, format = Cheffish::KeyFormatter.decode(user['public_key'])
58
- expect(key).to be_public_key_for("#{repo_path}/blah.pem")
59
- end
60
- end
61
- end
62
-
63
- context 'and chef_server_url is pointed at /organizations/foo' do
64
- organization 'foo'
65
-
66
- before :each do
67
- Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
68
- end
69
-
70
- context 'and we run a recipe that creates user "blah"'do
71
- it 'the user gets created' do
72
- expect_recipe {
73
- chef_user 'blah' do
74
- source_key_path "#{repo_path}/blah.pem"
75
- end
76
- }.to have_updated 'chef_user[blah]', :create
77
- user = get('/users/blah')
78
- expect(user['name']).to eq('blah')
79
- key, format = Cheffish::KeyFormatter.decode(user['public_key'])
80
- expect(key).to be_public_key_for("#{repo_path}/blah.pem")
81
- end
82
- end
83
- end
84
- end
85
- end
1
+ require 'support/spec_support'
2
+ require 'cheffish/rspec/chef_run_support'
3
+ require 'support/key_support'
4
+ require 'chef/resource/chef_user'
5
+ require 'chef/provider/chef_user'
6
+
7
+ repo_path = Dir.mktmpdir('chef_repo')
8
+
9
+ describe Chef::Resource::ChefUser do
10
+ extend Cheffish::RSpec::ChefRunSupport
11
+
12
+ with_converge do
13
+ private_key "#{repo_path}/blah.pem"
14
+ end
15
+
16
+ when_the_chef_server 'is empty' do
17
+ context 'and we run a recipe that creates user "blah"'do
18
+ it 'the user gets created' do
19
+ expect_recipe {
20
+ chef_user 'blah' do
21
+ source_key_path "#{repo_path}/blah.pem"
22
+ end
23
+ }.to have_updated 'chef_user[blah]', :create
24
+ user = get('/users/blah')
25
+ expect(user['name']).to eq('blah')
26
+ key, format = Cheffish::KeyFormatter.decode(user['public_key'])
27
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
28
+ end
29
+ end
30
+
31
+ context 'and we run a recipe that creates user "blah" with output_key_path' do
32
+ with_converge do
33
+ chef_user 'blah' do
34
+ source_key_path "#{repo_path}/blah.pem"
35
+ output_key_path "#{repo_path}/blah.pub"
36
+ end
37
+ end
38
+
39
+ it 'the output public key gets created' do
40
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
41
+ expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah.pem")
42
+ end
43
+ end
44
+ end
45
+
46
+ when_the_chef_12_server 'is in multi-org mode' do
47
+ context 'and chef_server_url is pointed at the top level' do
48
+ context 'and we run a recipe that creates user "blah"'do
49
+ it 'the user gets created' do
50
+ expect_recipe {
51
+ chef_user 'blah' do
52
+ source_key_path "#{repo_path}/blah.pem"
53
+ end
54
+ }.to have_updated 'chef_user[blah]', :create
55
+ user = get('/users/blah')
56
+ expect(user['name']).to eq('blah')
57
+ key, format = Cheffish::KeyFormatter.decode(user['public_key'])
58
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'and chef_server_url is pointed at /organizations/foo' do
64
+ organization 'foo'
65
+
66
+ before :each do
67
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
68
+ end
69
+
70
+ context 'and we run a recipe that creates user "blah"'do
71
+ it 'the user gets created' do
72
+ expect_recipe {
73
+ chef_user 'blah' do
74
+ source_key_path "#{repo_path}/blah.pem"
75
+ end
76
+ }.to have_updated 'chef_user[blah]', :create
77
+ user = get('/users/blah')
78
+ expect(user['name']).to eq('blah')
79
+ key, format = Cheffish::KeyFormatter.decode(user['public_key'])
80
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,399 +1,399 @@
1
- require 'support/spec_support'
2
- require 'cheffish/rspec/chef_run_support'
3
- require 'chef/resource/private_key'
4
- require 'chef/provider/private_key'
5
- require 'chef/resource/public_key'
6
- require 'chef/provider/public_key'
7
- require 'support/key_support'
8
-
9
- repo_path = Dir.mktmpdir('chef_repo')
10
-
11
- describe Chef::Resource::PrivateKey do
12
- extend Cheffish::RSpec::ChefRunSupport
13
-
14
- before :each do
15
- FileUtils.remove_entry_secure(repo_path)
16
- Dir.mkdir(repo_path)
17
- end
18
-
19
- context 'with a recipe with a private_key' do
20
- it 'the private_key is created in pem format' do
21
- expect_recipe {
22
- private_key "#{repo_path}/blah"
23
- }.to have_updated "private_key[#{repo_path}/blah]", :create
24
- expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
25
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
26
- end
27
- end
28
-
29
- context 'with a private_key "blah" resource' do
30
- before :each do
31
- Dir.mkdir("#{repo_path}/other_keys")
32
- Chef::Config.private_key_paths = [ repo_path, "#{repo_path}/other_keys" ]
33
- end
34
-
35
- it 'the private key is created in the private_key_write_path' do
36
- expect_recipe {
37
- private_key 'blah'
38
- }.to have_updated "private_key[blah]", :create
39
- expect(Chef::Config.private_key_write_path).to eq(repo_path)
40
- expect(File.exist?("#{repo_path}/blah")).to be true
41
- expect(File.exist?("#{repo_path}/other_keys/blah")).to be false
42
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
43
- expect(OpenSSL::PKey.read(Cheffish.get_private_key('blah'))).to be_kind_of(OpenSSL::PKey::RSA)
44
- end
45
-
46
- context 'and the private key already exists somewhere not in the write path' do
47
- before :each do
48
- recipe { private_key "#{repo_path}/other_keys/blah" }.converge
49
- end
50
-
51
- it 'the private expect(key).to not update' do
52
- expect_recipe {
53
- private_key 'blah'
54
- }.not_to have_updated "private_key[blah]", :create
55
-
56
- expect(File.exist?("#{repo_path}/blah")).to be false
57
- expect(File.exist?("#{repo_path}/other_keys/blah")).to be true
58
- end
59
- end
60
- end
61
-
62
- context 'with a private key' do
63
- before :each do
64
- Cheffish::BasicChefClient.converge_block do
65
- private_key "#{repo_path}/blah"
66
- end
67
- end
68
-
69
- context 'and a private_key that copies it in der format' do
70
- it 'the private_key is copied in der format and is identical' do
71
- expect_recipe {
72
- private_key "#{repo_path}/blah.der" do
73
- source_key_path "#{repo_path}/blah"
74
- format :der
75
- end
76
- }.to have_updated "private_key[#{repo_path}/blah.der]", :create
77
- key_str = IO.read("#{repo_path}/blah.der")
78
- expect(key_str).not_to start_with('-----BEGIN')
79
- expect(key_str).not_to start_with('ssh-')
80
- expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
81
- end
82
- end
83
-
84
- it 'a private_key that copies it from in-memory as a string succeeds' do
85
- expect_recipe {
86
- private_key "#{repo_path}/blah.der" do
87
- source_key IO.read("#{repo_path}/blah")
88
- format :der
89
- end
90
- }.to have_updated "private_key[#{repo_path}/blah.der]", :create
91
- key_str = IO.read("#{repo_path}/blah.der")
92
- expect(key_str).not_to start_with('-----BEGIN')
93
- expect(key_str).not_to start_with('ssh-')
94
- expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
95
- end
96
-
97
- it 'a private_key that copies it from in-memory as a key succeeds' do
98
- key = OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))
99
- expect_recipe {
100
- private_key "#{repo_path}/blah.der" do
101
- source_key key
102
- format :der
103
- end
104
- }.to have_updated "private_key[#{repo_path}/blah.der]", :create
105
- key_str = IO.read("#{repo_path}/blah.der")
106
- expect(key_str).not_to start_with('-----BEGIN')
107
- expect(key_str).not_to start_with('ssh-')
108
- expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
109
- end
110
-
111
- context 'and a public_key recipe' do
112
- it 'the public_key is created' do
113
- expect_recipe {
114
- public_key "#{repo_path}/blah.pub" do
115
- source_key_path "#{repo_path}/blah"
116
- end
117
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
118
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
119
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
120
- end
121
- end
122
-
123
- context 'and a public key' do
124
- before :each do
125
- Cheffish::BasicChefClient.converge_block do
126
- public_key "#{repo_path}/blah.pub" do
127
- source_key_path "#{repo_path}/blah"
128
- end
129
- end
130
- end
131
-
132
- context 'and public_key resource based off the public key file' do
133
- it 'the second public_key is created' do
134
- expect_recipe {
135
- public_key "#{repo_path}/blah.pub2" do
136
- source_key_path "#{repo_path}/blah.pub"
137
- end
138
- }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
139
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
140
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
141
- end
142
- end
143
-
144
- context 'and another public_key based off the first public_key in-memory in a string' do
145
- it 'the second public_key is created' do
146
- expect_recipe {
147
- public_key "#{repo_path}/blah.pub2" do
148
- source_key IO.read("#{repo_path}/blah.pub")
149
- end
150
- }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
151
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
152
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
153
- end
154
- end
155
-
156
- it 'and another public_key based off the first public_key in-memory in a key, the second public_key is created' do
157
- key, format = Cheffish::KeyFormatter.decode(IO.read("#{repo_path}/blah.pub"))
158
-
159
- expect_recipe {
160
- public_key "#{repo_path}/blah.pub2" do
161
- source_key key
162
- end
163
- }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
164
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
165
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
166
- end
167
-
168
- context 'and another public_key in :pem format based off the first public_key' do
169
- it 'the second public_key is created' do
170
- expect_recipe {
171
- public_key "#{repo_path}/blah.pub2" do
172
- source_key_path "#{repo_path}/blah.pub"
173
- format :pem
174
- end
175
- }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
176
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
177
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
178
- end
179
- end
180
-
181
- context 'and another public_key in :der format based off the first public_key' do
182
- it 'the second public_key is created' do
183
- expect_recipe {
184
- public_key "#{repo_path}/blah.pub2" do
185
- source_key_path "#{repo_path}/blah.pub"
186
- format :pem
187
- end
188
- }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
189
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
190
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
191
- end
192
- end
193
- end
194
-
195
- context 'and a public_key resource in pem format' do
196
- it 'the public_key is created' do
197
- expect_recipe {
198
- public_key "#{repo_path}/blah.pub" do
199
- source_key_path "#{repo_path}/blah"
200
- format :pem
201
- end
202
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
203
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('-----BEGIN')
204
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
205
- end
206
- end
207
-
208
- context 'and a public_key resource in der format' do
209
- it 'the public_key is created in openssh format' do
210
- expect_recipe {
211
- public_key "#{repo_path}/blah.pub" do
212
- source_key_path "#{repo_path}/blah"
213
- format :der
214
- end
215
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
216
- expect(IO.read("#{repo_path}/blah.pub")).not_to start_with('-----BEGIN')
217
- expect(IO.read("#{repo_path}/blah.pub")).not_to start_with('ssh-rsa')
218
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
219
- end
220
- end
221
- end
222
-
223
- context 'with a recipe with a private_key in der format' do
224
- it 'the private_key is created' do
225
- expect_recipe {
226
- private_key "#{repo_path}/blah" do
227
- format :der
228
- end
229
- }.to have_updated "private_key[#{repo_path}/blah]", :create
230
- expect(IO.read("#{repo_path}/blah")).not_to start_with('-----BEGIN')
231
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
232
- end
233
- end
234
-
235
- context 'with a private key in der format' do
236
- before :each do
237
- Cheffish::BasicChefClient.converge_block do
238
- private_key "#{repo_path}/blah" do
239
- format :der
240
- end
241
- end
242
- end
243
-
244
- context 'and a public_key' do
245
- it 'the public_key is created in openssh format' do
246
- expect_recipe {
247
- public_key "#{repo_path}/blah.pub" do
248
- source_key_path "#{repo_path}/blah"
249
- end
250
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
251
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
252
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
253
- end
254
- end
255
- end
256
-
257
- context 'with a recipe with a private_key with a pass_phrase' do
258
- it 'the private_key is created' do
259
- expect_recipe {
260
- private_key "#{repo_path}/blah" do
261
- pass_phrase 'hello'
262
- end
263
- }.to have_updated "private_key[#{repo_path}/blah]", :create
264
- expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
265
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"), 'hello')).to be_kind_of(OpenSSL::PKey::RSA)
266
- end
267
- end
268
-
269
- context 'with a private key with a pass phrase' do
270
- before :each do
271
- Cheffish::BasicChefClient.converge_block do
272
- private_key "#{repo_path}/blah" do
273
- pass_phrase 'hello'
274
- end
275
- end
276
- end
277
-
278
- context 'and a private_key that copies it in der format' do
279
- it 'the private_key is copied in der format and is identical' do
280
- expect_recipe {
281
- private_key "#{repo_path}/blah.der" do
282
- source_key_path "#{repo_path}/blah"
283
- source_key_pass_phrase 'hello'
284
- format :der
285
- end
286
- }.to have_updated "private_key[#{repo_path}/blah.der]", :create
287
- key_str = IO.read("#{repo_path}/blah.der")
288
- expect(key_str).not_to start_with('-----BEGIN')
289
- expect(key_str).not_to start_with('ssh-')
290
- expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah", 'hello')
291
- end
292
- end
293
-
294
- context 'and a private_key resource pointing at it without a pass_phrase' do
295
- it 'the run fails with an exception' do
296
- expect {
297
- converge {
298
- private_key "#{repo_path}/blah"
299
- }
300
- }.to raise_error /missing pass phrase?/
301
- end
302
- end
303
-
304
- context 'and a private_key resource with no pass phrase and regenerate_if_different' do
305
- it 'the private_key is regenerated' do
306
- expect_recipe {
307
- private_key "#{repo_path}/blah" do
308
- regenerate_if_different true
309
- end
310
- }.to have_updated "private_key[#{repo_path}/blah]", :create
311
- expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
312
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
313
- end
314
- end
315
-
316
- it 'a private_key resource that copies it from in-memory as a string succeeds' do
317
- expect_recipe {
318
- private_key "#{repo_path}/blah.der" do
319
- source_key IO.read("#{repo_path}/blah")
320
- source_key_pass_phrase 'hello'
321
- format :der
322
- end
323
- }.to have_updated "private_key[#{repo_path}/blah.der]", :create
324
- key_str = IO.read("#{repo_path}/blah.der")
325
- expect(key_str).not_to start_with('-----BEGIN')
326
- expect(key_str).not_to start_with('ssh-')
327
- expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah", 'hello')
328
- end
329
-
330
- context 'and a public_key' do
331
- it 'the public_key is created in openssh format' do
332
- expect_recipe {
333
- public_key "#{repo_path}/blah.pub" do
334
- source_key_path "#{repo_path}/blah"
335
- source_key_pass_phrase 'hello'
336
- end
337
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
338
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
339
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah", 'hello'
340
- end
341
- end
342
-
343
- context 'and a public_key derived from the private key in an in-memory string' do
344
- it 'the public_key is created in openssh format' do
345
- expect_recipe {
346
- public_key "#{repo_path}/blah.pub" do
347
- source_key IO.read("#{repo_path}/blah")
348
- source_key_pass_phrase 'hello'
349
- end
350
- }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
351
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
352
- expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah", 'hello'
353
- end
354
- end
355
- end
356
-
357
- context 'with a recipe with a private_key and public_key_path' do
358
- it 'the private_key and public_key are created' do
359
- expect_recipe {
360
- private_key "#{repo_path}/blah" do
361
- public_key_path "#{repo_path}/blah.pub"
362
- end
363
- }.to have_updated "private_key[#{repo_path}/blah]", :create
364
- expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
365
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
366
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
367
- expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah")
368
- end
369
- end
370
-
371
- context 'with a recipe with a private_key and public_key_path and public_key_format' do
372
- it 'the private_key and public_key are created' do
373
- expect_recipe {
374
- private_key "#{repo_path}/blah" do
375
- public_key_path "#{repo_path}/blah.pub.der"
376
- public_key_format :der
377
- end
378
- }.to have_updated "private_key[#{repo_path}/blah]", :create
379
- expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
380
- expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
381
- expect(IO.read("#{repo_path}/blah.pub.der")).not_to start_with('ssh-rsa ')
382
- expect("#{repo_path}/blah.pub.der").to be_public_key_for("#{repo_path}/blah")
383
- end
384
- end
385
-
386
- context 'with a recipe with a private_key with path :none' do
387
- it 'the private_key is created' do
388
- got_private_key = nil
389
- expect_recipe {
390
- private_key 'in_memory' do
391
- path :none
392
- after { |resource, private_key| got_private_key = private_key }
393
- end
394
- }.to have_updated "private_key[in_memory]", :create
395
- expect(got_private_key).to be_kind_of(OpenSSL::PKey::RSA)
396
- end
397
- end
398
-
399
- end
1
+ require 'support/spec_support'
2
+ require 'cheffish/rspec/chef_run_support'
3
+ require 'chef/resource/private_key'
4
+ require 'chef/provider/private_key'
5
+ require 'chef/resource/public_key'
6
+ require 'chef/provider/public_key'
7
+ require 'support/key_support'
8
+
9
+ repo_path = Dir.mktmpdir('chef_repo')
10
+
11
+ describe Chef::Resource::PrivateKey do
12
+ extend Cheffish::RSpec::ChefRunSupport
13
+
14
+ before :each do
15
+ FileUtils.remove_entry_secure(repo_path)
16
+ Dir.mkdir(repo_path)
17
+ end
18
+
19
+ context 'with a recipe with a private_key' do
20
+ it 'the private_key is created in pem format' do
21
+ expect_recipe {
22
+ private_key "#{repo_path}/blah"
23
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
24
+ expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
25
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
26
+ end
27
+ end
28
+
29
+ context 'with a private_key "blah" resource' do
30
+ before :each do
31
+ Dir.mkdir("#{repo_path}/other_keys")
32
+ Chef::Config.private_key_paths = [ repo_path, "#{repo_path}/other_keys" ]
33
+ end
34
+
35
+ it 'the private key is created in the private_key_write_path' do
36
+ expect_recipe {
37
+ private_key 'blah'
38
+ }.to have_updated "private_key[blah]", :create
39
+ expect(Chef::Config.private_key_write_path).to eq(repo_path)
40
+ expect(File.exist?("#{repo_path}/blah")).to be true
41
+ expect(File.exist?("#{repo_path}/other_keys/blah")).to be false
42
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
43
+ expect(OpenSSL::PKey.read(Cheffish.get_private_key('blah'))).to be_kind_of(OpenSSL::PKey::RSA)
44
+ end
45
+
46
+ context 'and the private key already exists somewhere not in the write path' do
47
+ before :each do
48
+ recipe { private_key "#{repo_path}/other_keys/blah" }.converge
49
+ end
50
+
51
+ it 'the private expect(key).to not update' do
52
+ expect_recipe {
53
+ private_key 'blah'
54
+ }.not_to have_updated "private_key[blah]", :create
55
+
56
+ expect(File.exist?("#{repo_path}/blah")).to be false
57
+ expect(File.exist?("#{repo_path}/other_keys/blah")).to be true
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'with a private key' do
63
+ before :each do
64
+ Cheffish::BasicChefClient.converge_block do
65
+ private_key "#{repo_path}/blah"
66
+ end
67
+ end
68
+
69
+ context 'and a private_key that copies it in der format' do
70
+ it 'the private_key is copied in der format and is identical' do
71
+ expect_recipe {
72
+ private_key "#{repo_path}/blah.der" do
73
+ source_key_path "#{repo_path}/blah"
74
+ format :der
75
+ end
76
+ }.to have_updated "private_key[#{repo_path}/blah.der]", :create
77
+ key_str = IO.read("#{repo_path}/blah.der")
78
+ expect(key_str).not_to start_with('-----BEGIN')
79
+ expect(key_str).not_to start_with('ssh-')
80
+ expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
81
+ end
82
+ end
83
+
84
+ it 'a private_key that copies it from in-memory as a string succeeds' do
85
+ expect_recipe {
86
+ private_key "#{repo_path}/blah.der" do
87
+ source_key IO.read("#{repo_path}/blah")
88
+ format :der
89
+ end
90
+ }.to have_updated "private_key[#{repo_path}/blah.der]", :create
91
+ key_str = IO.read("#{repo_path}/blah.der")
92
+ expect(key_str).not_to start_with('-----BEGIN')
93
+ expect(key_str).not_to start_with('ssh-')
94
+ expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
95
+ end
96
+
97
+ it 'a private_key that copies it from in-memory as a key succeeds' do
98
+ key = OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))
99
+ expect_recipe {
100
+ private_key "#{repo_path}/blah.der" do
101
+ source_key key
102
+ format :der
103
+ end
104
+ }.to have_updated "private_key[#{repo_path}/blah.der]", :create
105
+ key_str = IO.read("#{repo_path}/blah.der")
106
+ expect(key_str).not_to start_with('-----BEGIN')
107
+ expect(key_str).not_to start_with('ssh-')
108
+ expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah")
109
+ end
110
+
111
+ context 'and a public_key recipe' do
112
+ it 'the public_key is created' do
113
+ expect_recipe {
114
+ public_key "#{repo_path}/blah.pub" do
115
+ source_key_path "#{repo_path}/blah"
116
+ end
117
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
118
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
119
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
120
+ end
121
+ end
122
+
123
+ context 'and a public key' do
124
+ before :each do
125
+ Cheffish::BasicChefClient.converge_block do
126
+ public_key "#{repo_path}/blah.pub" do
127
+ source_key_path "#{repo_path}/blah"
128
+ end
129
+ end
130
+ end
131
+
132
+ context 'and public_key resource based off the public key file' do
133
+ it 'the second public_key is created' do
134
+ expect_recipe {
135
+ public_key "#{repo_path}/blah.pub2" do
136
+ source_key_path "#{repo_path}/blah.pub"
137
+ end
138
+ }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
139
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
140
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
141
+ end
142
+ end
143
+
144
+ context 'and another public_key based off the first public_key in-memory in a string' do
145
+ it 'the second public_key is created' do
146
+ expect_recipe {
147
+ public_key "#{repo_path}/blah.pub2" do
148
+ source_key IO.read("#{repo_path}/blah.pub")
149
+ end
150
+ }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
151
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
152
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
153
+ end
154
+ end
155
+
156
+ it 'and another public_key based off the first public_key in-memory in a key, the second public_key is created' do
157
+ key, format = Cheffish::KeyFormatter.decode(IO.read("#{repo_path}/blah.pub"))
158
+
159
+ expect_recipe {
160
+ public_key "#{repo_path}/blah.pub2" do
161
+ source_key key
162
+ end
163
+ }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
164
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
165
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
166
+ end
167
+
168
+ context 'and another public_key in :pem format based off the first public_key' do
169
+ it 'the second public_key is created' do
170
+ expect_recipe {
171
+ public_key "#{repo_path}/blah.pub2" do
172
+ source_key_path "#{repo_path}/blah.pub"
173
+ format :pem
174
+ end
175
+ }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
176
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
177
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
178
+ end
179
+ end
180
+
181
+ context 'and another public_key in :der format based off the first public_key' do
182
+ it 'the second public_key is created' do
183
+ expect_recipe {
184
+ public_key "#{repo_path}/blah.pub2" do
185
+ source_key_path "#{repo_path}/blah.pub"
186
+ format :pem
187
+ end
188
+ }.to have_updated "public_key[#{repo_path}/blah.pub2]", :create
189
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
190
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
191
+ end
192
+ end
193
+ end
194
+
195
+ context 'and a public_key resource in pem format' do
196
+ it 'the public_key is created' do
197
+ expect_recipe {
198
+ public_key "#{repo_path}/blah.pub" do
199
+ source_key_path "#{repo_path}/blah"
200
+ format :pem
201
+ end
202
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
203
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('-----BEGIN')
204
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
205
+ end
206
+ end
207
+
208
+ context 'and a public_key resource in der format' do
209
+ it 'the public_key is created in openssh format' do
210
+ expect_recipe {
211
+ public_key "#{repo_path}/blah.pub" do
212
+ source_key_path "#{repo_path}/blah"
213
+ format :der
214
+ end
215
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
216
+ expect(IO.read("#{repo_path}/blah.pub")).not_to start_with('-----BEGIN')
217
+ expect(IO.read("#{repo_path}/blah.pub")).not_to start_with('ssh-rsa')
218
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
219
+ end
220
+ end
221
+ end
222
+
223
+ context 'with a recipe with a private_key in der format' do
224
+ it 'the private_key is created' do
225
+ expect_recipe {
226
+ private_key "#{repo_path}/blah" do
227
+ format :der
228
+ end
229
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
230
+ expect(IO.read("#{repo_path}/blah")).not_to start_with('-----BEGIN')
231
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
232
+ end
233
+ end
234
+
235
+ context 'with a private key in der format' do
236
+ before :each do
237
+ Cheffish::BasicChefClient.converge_block do
238
+ private_key "#{repo_path}/blah" do
239
+ format :der
240
+ end
241
+ end
242
+ end
243
+
244
+ context 'and a public_key' do
245
+ it 'the public_key is created in openssh format' do
246
+ expect_recipe {
247
+ public_key "#{repo_path}/blah.pub" do
248
+ source_key_path "#{repo_path}/blah"
249
+ end
250
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
251
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
252
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah"
253
+ end
254
+ end
255
+ end
256
+
257
+ context 'with a recipe with a private_key with a pass_phrase' do
258
+ it 'the private_key is created' do
259
+ expect_recipe {
260
+ private_key "#{repo_path}/blah" do
261
+ pass_phrase 'hello'
262
+ end
263
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
264
+ expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
265
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"), 'hello')).to be_kind_of(OpenSSL::PKey::RSA)
266
+ end
267
+ end
268
+
269
+ context 'with a private key with a pass phrase' do
270
+ before :each do
271
+ Cheffish::BasicChefClient.converge_block do
272
+ private_key "#{repo_path}/blah" do
273
+ pass_phrase 'hello'
274
+ end
275
+ end
276
+ end
277
+
278
+ context 'and a private_key that copies it in der format' do
279
+ it 'the private_key is copied in der format and is identical' do
280
+ expect_recipe {
281
+ private_key "#{repo_path}/blah.der" do
282
+ source_key_path "#{repo_path}/blah"
283
+ source_key_pass_phrase 'hello'
284
+ format :der
285
+ end
286
+ }.to have_updated "private_key[#{repo_path}/blah.der]", :create
287
+ key_str = IO.read("#{repo_path}/blah.der")
288
+ expect(key_str).not_to start_with('-----BEGIN')
289
+ expect(key_str).not_to start_with('ssh-')
290
+ expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah", 'hello')
291
+ end
292
+ end
293
+
294
+ context 'and a private_key resource pointing at it without a pass_phrase' do
295
+ it 'the run fails with an exception' do
296
+ expect {
297
+ converge {
298
+ private_key "#{repo_path}/blah"
299
+ }
300
+ }.to raise_error /missing pass phrase?/
301
+ end
302
+ end
303
+
304
+ context 'and a private_key resource with no pass phrase and regenerate_if_different' do
305
+ it 'the private_key is regenerated' do
306
+ expect_recipe {
307
+ private_key "#{repo_path}/blah" do
308
+ regenerate_if_different true
309
+ end
310
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
311
+ expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
312
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
313
+ end
314
+ end
315
+
316
+ it 'a private_key resource that copies it from in-memory as a string succeeds' do
317
+ expect_recipe {
318
+ private_key "#{repo_path}/blah.der" do
319
+ source_key IO.read("#{repo_path}/blah")
320
+ source_key_pass_phrase 'hello'
321
+ format :der
322
+ end
323
+ }.to have_updated "private_key[#{repo_path}/blah.der]", :create
324
+ key_str = IO.read("#{repo_path}/blah.der")
325
+ expect(key_str).not_to start_with('-----BEGIN')
326
+ expect(key_str).not_to start_with('ssh-')
327
+ expect("#{repo_path}/blah.der").to match_private_key("#{repo_path}/blah", 'hello')
328
+ end
329
+
330
+ context 'and a public_key' do
331
+ it 'the public_key is created in openssh format' do
332
+ expect_recipe {
333
+ public_key "#{repo_path}/blah.pub" do
334
+ source_key_path "#{repo_path}/blah"
335
+ source_key_pass_phrase 'hello'
336
+ end
337
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
338
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
339
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah", 'hello'
340
+ end
341
+ end
342
+
343
+ context 'and a public_key derived from the private key in an in-memory string' do
344
+ it 'the public_key is created in openssh format' do
345
+ expect_recipe {
346
+ public_key "#{repo_path}/blah.pub" do
347
+ source_key IO.read("#{repo_path}/blah")
348
+ source_key_pass_phrase 'hello'
349
+ end
350
+ }.to have_updated "public_key[#{repo_path}/blah.pub]", :create
351
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
352
+ expect("#{repo_path}/blah.pub").to be_public_key_for "#{repo_path}/blah", 'hello'
353
+ end
354
+ end
355
+ end
356
+
357
+ context 'with a recipe with a private_key and public_key_path' do
358
+ it 'the private_key and public_key are created' do
359
+ expect_recipe {
360
+ private_key "#{repo_path}/blah" do
361
+ public_key_path "#{repo_path}/blah.pub"
362
+ end
363
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
364
+ expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
365
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
366
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
367
+ expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah")
368
+ end
369
+ end
370
+
371
+ context 'with a recipe with a private_key and public_key_path and public_key_format' do
372
+ it 'the private_key and public_key are created' do
373
+ expect_recipe {
374
+ private_key "#{repo_path}/blah" do
375
+ public_key_path "#{repo_path}/blah.pub.der"
376
+ public_key_format :der
377
+ end
378
+ }.to have_updated "private_key[#{repo_path}/blah]", :create
379
+ expect(IO.read("#{repo_path}/blah")).to start_with('-----BEGIN')
380
+ expect(OpenSSL::PKey.read(IO.read("#{repo_path}/blah"))).to be_kind_of(OpenSSL::PKey::RSA)
381
+ expect(IO.read("#{repo_path}/blah.pub.der")).not_to start_with('ssh-rsa ')
382
+ expect("#{repo_path}/blah.pub.der").to be_public_key_for("#{repo_path}/blah")
383
+ end
384
+ end
385
+
386
+ context 'with a recipe with a private_key with path :none' do
387
+ it 'the private_key is created' do
388
+ got_private_key = nil
389
+ expect_recipe {
390
+ private_key 'in_memory' do
391
+ path :none
392
+ after { |resource, private_key| got_private_key = private_key }
393
+ end
394
+ }.to have_updated "private_key[in_memory]", :create
395
+ expect(got_private_key).to be_kind_of(OpenSSL::PKey::RSA)
396
+ end
397
+ end
398
+
399
+ end