knife-ec-backup 2.2.1 → 2.2.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/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: {}
|