knife-ec-backup 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/knife/ec_backup.rb +11 -7
- data/lib/chef/knife/ec_error_handler.rb +13 -2
- data/lib/chef/knife/ec_restore.rb +18 -7
- data/lib/chef/server.rb +4 -0
- data/lib/knife_ec_backup/version.rb +1 -1
- data/spec/chef/knife/ec_backup_spec.rb +25 -1
- data/spec/chef/knife/ec_error_handler_spec.rb +30 -0
- data/spec/chef/knife/ec_restore_spec.rb +24 -0
- data/spec/chef/server_spec.rb +9 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f28320438d24209115a64e91cec7e5d2646b0f
|
4
|
+
data.tar.gz: 7fb944b92530e55b91674ee719622e59805fb561
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f992491a7740086eb463b27ea99dcfb7f772d8e6809d10ee1dc286976b4041c112d9f8f2078f049d2e3a0557196731d237bef544295978b20021bc89fd60b2c
|
7
|
+
data.tar.gz: 70d19c19168130fa803d38db9df39c70c49feab8a052746977b2c6dda8da2c7d3da0f5fb6b620fc91bbc006e712affc3ff1141eb1d26b76c093c59ca809d7da9
|
data/lib/chef/knife/ec_backup.rb
CHANGED
@@ -186,11 +186,13 @@ class Chef
|
|
186
186
|
|
187
187
|
# Download the billing-admins, public_key_read_access ACL and group as pivotal
|
188
188
|
chef_fs_config = Chef::ChefFS::Config.new
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
189
|
+
|
190
|
+
paths = ['/acls/groups/billing-admins.json', '/groups/billing-admins.json', '/groups/admins.json']
|
191
|
+
paths.push('/acls/groups/public_key_read_access.json', '/groups/public_key_read_access.json') if server.supports_public_key_read_access?
|
192
|
+
|
193
|
+
paths.each do |path|
|
194
|
+
chef_fs_copy_pattern(path, chef_fs_config)
|
195
|
+
end
|
194
196
|
|
195
197
|
Chef::Config.node_name = if config[:skip_version]
|
196
198
|
org_admin
|
@@ -210,7 +212,7 @@ class Chef
|
|
210
212
|
# for example: /acls/environments/_default
|
211
213
|
|
212
214
|
# Skip the billing-admins, public_key_read_access group ACLs and the groups since they've already been copied
|
213
|
-
exclude_list = ['billing-admins','public_key_read_access']
|
215
|
+
exclude_list = ['billing-admins', 'public_key_read_access']
|
214
216
|
|
215
217
|
top_level_acls = chef_fs_paths('/acls/*.json', chef_fs_config, [])
|
216
218
|
acl_paths = chef_fs_paths('/acls/*/*', chef_fs_config, exclude_list)
|
@@ -241,7 +243,9 @@ class Chef
|
|
241
243
|
chef_fs_config.local_fs, nil,
|
242
244
|
config, ui,
|
243
245
|
proc { |entry| chef_fs_config.format_path(entry) })
|
244
|
-
rescue Net::HTTPServerException
|
246
|
+
rescue Net::HTTPServerException,
|
247
|
+
Chef::ChefFS::FileSystem::NotFoundError,
|
248
|
+
Chef::ChefFS::FileSystem::OperationFailedError => ex
|
245
249
|
knife_ec_error_handler.add(ex)
|
246
250
|
end
|
247
251
|
end
|
@@ -69,10 +69,21 @@ class Chef
|
|
69
69
|
}
|
70
70
|
|
71
71
|
if ex.respond_to?(:chef_rest_request=) && ex.chef_rest_request
|
72
|
-
msg.merge!(
|
72
|
+
msg.merge!(
|
73
73
|
req_path: ex.chef_rest_request.path,
|
74
74
|
req_method: ex.chef_rest_request.method
|
75
|
-
|
75
|
+
)
|
76
|
+
elsif ex.instance_of?(Chef::ChefFS::FileSystem::NotFoundError)
|
77
|
+
msg.merge!(
|
78
|
+
entry: ex.entry,
|
79
|
+
cause: ex.cause,
|
80
|
+
reason: ex.reason
|
81
|
+
)
|
82
|
+
elsif ex.instance_of?(Chef::ChefFS::FileSystem::OperationFailedError)
|
83
|
+
msg.merge!(
|
84
|
+
entry: ex.entry,
|
85
|
+
operation: ex.operation
|
86
|
+
)
|
76
87
|
end
|
77
88
|
|
78
89
|
lock_file(@err_file, 'a') do |f|
|
@@ -238,11 +238,19 @@ class Chef
|
|
238
238
|
# pivotal and members of the admins group. Use the same strategy
|
239
239
|
# above here.
|
240
240
|
#
|
241
|
-
['admins', 'billing-admins'
|
241
|
+
groups = ['admins', 'billing-admins']
|
242
|
+
groups.push('public_key_read_access') if
|
243
|
+
::File.exist?(::File.join(chef_fs_config.local_fs.child_paths['groups'], 'public_key_read_access.json'))
|
244
|
+
|
245
|
+
groups.each do |group|
|
242
246
|
restore_group(chef_fs_config, group, :clients => false)
|
243
247
|
end
|
244
248
|
|
245
|
-
['/acls/groups/billing-admins.json'
|
249
|
+
acls_groups_paths = ['/acls/groups/billing-admins.json']
|
250
|
+
acls_groups_paths.push('/acls/groups/public_key_read_access.json') if
|
251
|
+
::File.exist?(::File.join(chef_fs_config.local_fs.child_paths['acls'], 'groups', 'public_key_read_access.json'))
|
252
|
+
|
253
|
+
acls_groups_paths.each do |acl|
|
246
254
|
chef_fs_copy_pattern(acl, chef_fs_config)
|
247
255
|
end
|
248
256
|
|
@@ -258,13 +266,13 @@ class Chef
|
|
258
266
|
top_level_paths = chef_fs_config.local_fs.children.select { |entry| entry.name != 'acls' && entry.name != 'groups' }.map { |entry| entry.path }
|
259
267
|
|
260
268
|
# Topologically sort groups for upload
|
261
|
-
|
269
|
+
filenames = ['billing-admins.json', 'public_key_read_access.json']
|
270
|
+
unsorted_groups = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/groups/*')).select { |entry| ! filenames.include?(entry.name) }.map { |entry| JSON.parse(entry.read) }
|
262
271
|
group_paths = sort_groups_for_upload(unsorted_groups).map { |group_name| "/groups/#{group_name}.json" }
|
263
272
|
|
264
|
-
group_acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| !
|
273
|
+
group_acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| ! filenames.include?(entry.name) }.map { |entry| entry.path }
|
265
274
|
acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
|
266
275
|
|
267
|
-
|
268
276
|
# Store organization data in a particular order:
|
269
277
|
# - clients must be uploaded before groups (in top_level_paths)
|
270
278
|
# - groups must be uploaded before any acl's
|
@@ -276,7 +284,7 @@ class Chef
|
|
276
284
|
|
277
285
|
# restore clients to groups, using the pivotal user again
|
278
286
|
Chef::Config[:node_name] = 'pivotal'
|
279
|
-
|
287
|
+
groups.each do |group|
|
280
288
|
restore_group(Chef::ChefFS::Config.new, group)
|
281
289
|
end
|
282
290
|
ensure
|
@@ -297,7 +305,9 @@ class Chef
|
|
297
305
|
chef_fs_config.chef_fs, nil,
|
298
306
|
config, ui,
|
299
307
|
proc { |entry| chef_fs_config.format_path(entry) })
|
300
|
-
rescue Net::HTTPServerException
|
308
|
+
rescue Net::HTTPServerException,
|
309
|
+
Chef::ChefFS::FileSystem::NotFoundError,
|
310
|
+
Chef::ChefFS::FileSystem::OperationFailedError => ex
|
301
311
|
knife_ec_error_handler.add(ex)
|
302
312
|
end
|
303
313
|
|
@@ -324,6 +334,7 @@ class Chef
|
|
324
334
|
includes[:users] = true unless includes.key? :users
|
325
335
|
includes[:clients] = true unless includes.key? :clients
|
326
336
|
|
337
|
+
ui.msg "Copying /groups/#{group_name}.json"
|
327
338
|
group = Chef::ChefFS::FileSystem.resolve_path(
|
328
339
|
chef_fs_config.chef_fs,
|
329
340
|
"/groups/#{group_name}.json"
|
data/lib/chef/server.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
2
|
require 'chef/knife/ec_backup'
|
3
3
|
require 'fakefs/spec_helpers'
|
4
|
+
require_relative './ec_error_handler_spec'
|
5
|
+
require "chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir"
|
6
|
+
|
4
7
|
|
5
8
|
describe Chef::Knife::EcBackup do
|
6
9
|
let(:dest_dir) { Dir.mktmpdir }
|
@@ -162,6 +165,28 @@ describe Chef::Knife::EcBackup do
|
|
162
165
|
end
|
163
166
|
end
|
164
167
|
|
168
|
+
describe "#chef_fs_copy_pattern" do
|
169
|
+
context "when there are Filesystem errors" do
|
170
|
+
let(:ec_error_handler) { double("Chef::Knife::EcErrorHandler") }
|
171
|
+
let(:cheffs_config) { double("Chef::ChefFS::Config") }
|
172
|
+
let(:cheffs_files) { double("Chef::ChefFS::FileSystem") }
|
173
|
+
let(:cheffs_local_fs) { double('Chef::ChefFS::FileSystem::Repository::ChefRepositoryFileSystemRootDir') }
|
174
|
+
let(:chef_fs) { double('applefs') }
|
175
|
+
|
176
|
+
it "adds exceptions to error handler" do
|
177
|
+
exception = cheffs_filesystem_exception('NotFoundError')
|
178
|
+
allow(Chef::Knife::EcErrorHandler).to receive(:new).and_return(ec_error_handler)
|
179
|
+
allow(Chef::ChefFS::Config).to receive(:new).and_return(cheffs_config)
|
180
|
+
allow(Chef::ChefFS::FileSystem::Repository::ChefRepositoryFileSystemRootDir).to receive(:new).and_return(cheffs_local_fs)
|
181
|
+
allow(Chef::ChefFS::FileSystem).to receive(:copy_to).with(any_args).and_raise(exception)
|
182
|
+
allow(cheffs_config).to receive(:chef_fs).and_return(chef_fs)
|
183
|
+
allow(cheffs_config).to receive(:local_fs).and_return(cheffs_local_fs)
|
184
|
+
expect(ec_error_handler).to receive(:add).at_least(1).with(exception)
|
185
|
+
@knife.chef_fs_copy_pattern('bob', cheffs_config)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
165
190
|
describe "#write_org_object_to_disk" do
|
166
191
|
include FakeFS::SpecHelpers
|
167
192
|
it "writes the given object to disk" do
|
@@ -205,7 +230,6 @@ describe Chef::Knife::EcBackup do
|
|
205
230
|
@knife.download_org_members("bob")
|
206
231
|
end
|
207
232
|
end
|
208
|
-
|
209
233
|
end
|
210
234
|
|
211
235
|
describe "#download_org_inivitations" do
|
@@ -2,6 +2,8 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_hel
|
|
2
2
|
require 'chef/knife/ec_error_handler'
|
3
3
|
require 'chef/knife/ec_backup'
|
4
4
|
require 'chef/knife/ec_restore'
|
5
|
+
require 'chef/chef_fs/config'
|
6
|
+
require 'chef/chef_fs/file_system'
|
5
7
|
require 'fakefs/spec_helpers'
|
6
8
|
|
7
9
|
def net_exception(code)
|
@@ -9,6 +11,17 @@ def net_exception(code)
|
|
9
11
|
Net::HTTPServerException.new("I'm not real!", s)
|
10
12
|
end
|
11
13
|
|
14
|
+
def cheffs_filesystem_exception(type)
|
15
|
+
case type
|
16
|
+
when 'NotFoundError'
|
17
|
+
Chef::ChefFS::FileSystem::NotFoundError.new('/boop', 'The exception', 'The reason')
|
18
|
+
when 'OperationFailedError'
|
19
|
+
Chef::ChefFS::FileSystem::OperationFailedError.new(:read, '/boop', 'The exception', 'The reason')
|
20
|
+
else
|
21
|
+
raise RuntimeError, 'invalid type passed'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
12
25
|
describe Chef::Knife::EcErrorHandler do
|
13
26
|
let(:dest_dir) { Dir.mktmpdir }
|
14
27
|
let(:err_dir) { File.join(dest_dir, "errors") }
|
@@ -69,6 +82,21 @@ Error Summary Report
|
|
69
82
|
"message": "I'm not real!",
|
70
83
|
"backtrace": null,
|
71
84
|
"exception": "Net::HTTPServerException"
|
85
|
+
}{
|
86
|
+
"timestamp": "1988-04-17 00:00:00 +0000",
|
87
|
+
"message": "The reason",
|
88
|
+
"backtrace": null,
|
89
|
+
"exception": "Chef::ChefFS::FileSystem::NotFoundError",
|
90
|
+
"entry": "/boop",
|
91
|
+
"cause": "The exception",
|
92
|
+
"reason": "The reason"
|
93
|
+
}{
|
94
|
+
"timestamp": "1988-04-17 00:00:00 +0000",
|
95
|
+
"message": "The reason",
|
96
|
+
"backtrace": null,
|
97
|
+
"exception": "Chef::ChefFS::FileSystem::OperationFailedError",
|
98
|
+
"entry": "/boop",
|
99
|
+
"operation": "read"
|
72
100
|
}
|
73
101
|
EOF
|
74
102
|
err_file = @knife_ec_error_handler.err_file
|
@@ -83,6 +111,8 @@ EOF
|
|
83
111
|
@knife_ec_error_handler.add(net_exception(409))
|
84
112
|
@knife_ec_error_handler.add(net_exception(404))
|
85
113
|
@knife_ec_error_handler.add(net_exception(123))
|
114
|
+
@knife_ec_error_handler.add(cheffs_filesystem_exception('NotFoundError'))
|
115
|
+
@knife_ec_error_handler.add(cheffs_filesystem_exception('OperationFailedError'))
|
86
116
|
expect(File.read(err_file)).to match mock_content.strip
|
87
117
|
end
|
88
118
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
2
|
require 'chef/knife/ec_restore'
|
3
3
|
require 'fakefs/spec_helpers'
|
4
|
+
require_relative './ec_error_handler_spec'
|
5
|
+
require "chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir"
|
4
6
|
|
5
7
|
def make_user(username)
|
6
8
|
FileUtils.mkdir_p("/users")
|
@@ -159,4 +161,26 @@ describe Chef::Knife::EcRestore do
|
|
159
161
|
end
|
160
162
|
end
|
161
163
|
end
|
164
|
+
|
165
|
+
describe "#chef_fs_copy_pattern" do
|
166
|
+
context "when there are Filesystem errors" do
|
167
|
+
let(:ec_error_handler) { double("Chef::Knife::EcErrorHandler") }
|
168
|
+
let(:cheffs_config) { double("Chef::ChefFS::Config") }
|
169
|
+
let(:cheffs_files) { double("Chef::ChefFS::FileSystem") }
|
170
|
+
let(:cheffs_local_fs) { double('Chef::ChefFS::FileSystem::Repository::ChefRepositoryFileSystemRootDir') }
|
171
|
+
let(:chef_fs) { double('applefs') }
|
172
|
+
|
173
|
+
it "adds exceptions to error handler" do
|
174
|
+
exception = cheffs_filesystem_exception('NotFoundError')
|
175
|
+
allow(Chef::Knife::EcErrorHandler).to receive(:new).and_return(ec_error_handler)
|
176
|
+
allow(Chef::ChefFS::Config).to receive(:new).and_return(cheffs_config)
|
177
|
+
allow(Chef::ChefFS::FileSystem::Repository::ChefRepositoryFileSystemRootDir).to receive(:new).and_return(cheffs_local_fs)
|
178
|
+
allow(Chef::ChefFS::FileSystem).to receive(:copy_to).with(any_args).and_raise(exception)
|
179
|
+
allow(cheffs_config).to receive(:chef_fs).and_return(chef_fs)
|
180
|
+
allow(cheffs_config).to receive(:local_fs).and_return(cheffs_local_fs)
|
181
|
+
expect(ec_error_handler).to receive(:add).at_least(1).with(exception)
|
182
|
+
@knife.chef_fs_copy_pattern('bob', cheffs_config)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
162
186
|
end
|
data/spec/chef/server_spec.rb
CHANGED
@@ -47,4 +47,13 @@ describe Chef::Server do
|
|
47
47
|
allow(rest).to receive(:get).and_raise(Errno::ECONNREFUSED)
|
48
48
|
expect(s.direct_account_access?).to eq(false)
|
49
49
|
end
|
50
|
+
|
51
|
+
it "knows that public_key_read_access was implemented in 12.5.0" do
|
52
|
+
before = Chef::Server.new("http://api.example.com")
|
53
|
+
allow(before).to receive(:open).and_return(StringIO.new("Chef Server 12.4.1\nother stuff\nother stuff"))
|
54
|
+
expect(before.supports_public_key_read_access?).to eq(false)
|
55
|
+
after = Chef::Server.new("http://api.example.com")
|
56
|
+
allow(after).to receive(:open).and_return(StringIO.new("Chef Server 12.6.0\nother stuff\nother stuff"))
|
57
|
+
expect(after.supports_public_key_read_access?).to eq(true)
|
58
|
+
end
|
50
59
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-ec-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07
|
11
|
+
date: 2017-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: Backup and Restore of Enterprise Chef
|
70
|
-
email: jkeiser@
|
70
|
+
email: jkeiser@chef.io
|
71
71
|
executables: []
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files:
|
@@ -98,7 +98,7 @@ files:
|
|
98
98
|
- spec/chef/server_spec.rb
|
99
99
|
- spec/chef/tsorter_spec.rb
|
100
100
|
- spec/spec_helper.rb
|
101
|
-
homepage:
|
101
|
+
homepage: https://www.chef.io
|
102
102
|
licenses:
|
103
103
|
- Apache 2.0
|
104
104
|
metadata: {}
|