knife-ec-backup 1.2.0 → 2.0.0.beta.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.
- checksums.yaml +4 -4
- data/README.md +6 -4
- data/lib/chef/knife/ec_backup.rb +36 -28
- data/lib/chef/knife/ec_key_base.rb +2 -1
- data/lib/chef/knife/ec_key_export.rb +1 -1
- data/lib/chef/knife/ec_key_import.rb +15 -5
- data/lib/chef/knife/ec_restore.rb +91 -67
- data/lib/knife_ec_backup/version.rb +1 -1
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24f0f5bf6187090c18829999dd6ae339b8f97f44
|
4
|
+
data.tar.gz: c90dc04b94f007fb059a03021e2d951411e60d92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8f804e4a2a9bcc0486c86f618af446f3d8cea3a8ce002a39705db49652d6301ac5d68d65b1224c0f5b2db60a8eca620b50c0012a3fabff08ce40762555f1389
|
7
|
+
data.tar.gz: 0c5f596befa740f26deb0b7bc4bc50065333904d039ce22ded2e9bf02768e5c0475660c4a2d7723d1359901372a58b50463408b2683b6f6e9cfc56f65e469f69
|
data/README.md
CHANGED
@@ -6,9 +6,12 @@ This is an UNOFFICIAL and EXPERIMENTAL knife plugin intended to back up and rest
|
|
6
6
|
|
7
7
|
# Requirements
|
8
8
|
|
9
|
-
This knife plugin
|
9
|
+
This knife plugin requires Chef 11.8+.
|
10
10
|
|
11
|
-
|
11
|
+
## Chef 10
|
12
|
+
|
13
|
+
Users who are still using Chef 10 can use the most recent 1.x version
|
14
|
+
of this gem. Version 1.x additionally depends on knife-essentials.
|
12
15
|
|
13
16
|
# Installation
|
14
17
|
|
@@ -16,7 +19,6 @@ This knife plugin currently requires the Knife-Essentials gem to be installed in
|
|
16
19
|
This will install the plugin directly on the Chef Server:
|
17
20
|
|
18
21
|
/opt/opscode/embedded/bin/gem install knife-ec-backup
|
19
|
-
/opt/opscode/embedded/bin/gem install knife-ec-backup
|
20
22
|
|
21
23
|
## Build from source
|
22
24
|
Clone the git repository and run the following from inside:
|
@@ -118,4 +120,4 @@ Restores all data from a repository to an Enterprise Chef / Private Chef server.
|
|
118
120
|
* Single org backups.
|
119
121
|
* This plugin does **NOT** currently backup user passwords. **They will have to be reset after a restore.**
|
120
122
|
* This plugin does **NOT** currently restore user public keys. **Private keys will have to be reset after a restore.**
|
121
|
-
* This plugin does **NOT** currently restore custom user ACLs. **It will revert back to default ACLs on a restore.**
|
123
|
+
* This plugin does **NOT** currently restore custom user ACLs. **It will revert back to default ACLs on a restore.**
|
data/lib/chef/knife/ec_backup.rb
CHANGED
@@ -25,21 +25,25 @@ class Chef
|
|
25
25
|
:default => false,
|
26
26
|
:description => "Whether to skip checking the Chef Server version. This will also skip any auto-configured options"
|
27
27
|
|
28
|
+
option :with_user_sql,
|
29
|
+
:long => '--with-user-sql',
|
30
|
+
:description => 'Whether to try direct data base access for user export. Required to properly handle passwords, keys, and USAGs'
|
31
|
+
|
28
32
|
option :org,
|
29
33
|
:long => '--only-org ORGNAME',
|
30
34
|
:description => "Only back up objects in the named organization (default: all orgs)"
|
31
35
|
|
32
36
|
deps do
|
33
|
-
require 'chef_fs/config'
|
34
|
-
require 'chef_fs/file_system'
|
35
|
-
require 'chef_fs/file_pattern'
|
36
|
-
require 'chef_fs/parallelizer'
|
37
|
+
require 'chef/chef_fs/config'
|
38
|
+
require 'chef/chef_fs/file_system'
|
39
|
+
require 'chef/chef_fs/file_pattern'
|
40
|
+
require 'chef/chef_fs/parallelizer'
|
37
41
|
end
|
38
42
|
|
39
43
|
def configure_chef
|
40
44
|
super
|
41
45
|
Chef::Config[:concurrency] = config[:concurrency].to_i if config[:concurrency]
|
42
|
-
::ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
|
46
|
+
Chef::ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
|
43
47
|
end
|
44
48
|
|
45
49
|
def run
|
@@ -122,7 +126,6 @@ class Chef
|
|
122
126
|
|
123
127
|
# Grab users
|
124
128
|
puts "Grabbing users ..."
|
125
|
-
|
126
129
|
ensure_dir("#{dest_dir}/users")
|
127
130
|
ensure_dir("#{dest_dir}/user_acls")
|
128
131
|
|
@@ -141,6 +144,16 @@ class Chef
|
|
141
144
|
end
|
142
145
|
end
|
143
146
|
|
147
|
+
if config[:with_user_sql]
|
148
|
+
require 'chef/knife/ec_key_export'
|
149
|
+
Chef::Knife::EcKeyExport.deps
|
150
|
+
k = Chef::Knife::EcKeyExport.new
|
151
|
+
k.name_args = ["#{dest_dir}/key_dump.json"]
|
152
|
+
k.config[:sql_host] = "localhost"
|
153
|
+
k.config[:sql_port] = 5432
|
154
|
+
k.run
|
155
|
+
end
|
156
|
+
|
144
157
|
# Download organizations
|
145
158
|
ensure_dir("#{dest_dir}/organizations")
|
146
159
|
rest.get_rest('/organizations').each_pair do |name, url|
|
@@ -174,16 +187,13 @@ class Chef
|
|
174
187
|
end
|
175
188
|
|
176
189
|
PATHS = %w(chef_repo_path cookbook_path environment_path data_bag_path role_path node_path client_path acl_path group_path container_path)
|
177
|
-
CONFIG_VARS = %w(chef_server_url chef_server_root custom_http_headers node_name client_key versioned_cookbooks) + PATHS
|
178
190
|
def download_org(dest_dir, webui_key, name)
|
179
|
-
old_config =
|
180
|
-
|
181
|
-
old_config[key] = Chef::Config[key.to_sym]
|
182
|
-
end
|
191
|
+
old_config = Chef::Config.save
|
192
|
+
|
183
193
|
begin
|
184
194
|
# Clear out paths
|
185
|
-
PATHS.each do |
|
186
|
-
Chef::Config
|
195
|
+
PATHS.each do |path|
|
196
|
+
Chef::Config.delete(path.to_sym)
|
187
197
|
end
|
188
198
|
Chef::Config.chef_repo_path = "#{dest_dir}/organizations/#{name}"
|
189
199
|
Chef::Config.versioned_cookbooks = true
|
@@ -193,17 +203,17 @@ class Chef
|
|
193
203
|
ensure_dir(Chef::Config.chef_repo_path)
|
194
204
|
|
195
205
|
# Download the billing-admins ACL and group as pivotal
|
196
|
-
chef_fs_config = ::ChefFS::Config.new
|
197
|
-
pattern = ::ChefFS::FilePattern.new('/acls/groups/billing-admins.json')
|
198
|
-
if ::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
206
|
+
chef_fs_config = Chef::ChefFS::Config.new
|
207
|
+
pattern = Chef::ChefFS::FilePattern.new('/acls/groups/billing-admins.json')
|
208
|
+
if Chef::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
199
209
|
@error = true
|
200
210
|
end
|
201
|
-
pattern = ::ChefFS::FilePattern.new('/groups/billing-admins.json')
|
202
|
-
if ::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
211
|
+
pattern = Chef::ChefFS::FilePattern.new('/groups/billing-admins.json')
|
212
|
+
if Chef::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
203
213
|
@error = true
|
204
214
|
end
|
205
|
-
pattern = ::ChefFS::FilePattern.new('/groups/admins.json')
|
206
|
-
if ::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
215
|
+
pattern = Chef::ChefFS::FilePattern.new('/groups/admins.json')
|
216
|
+
if Chef::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
207
217
|
@error = true
|
208
218
|
end
|
209
219
|
|
@@ -217,19 +227,17 @@ class Chef
|
|
217
227
|
Chef::Config.custom_http_headers = (Chef::Config.custom_http_headers || {}).merge({'x-ops-request-source' => 'web'})
|
218
228
|
|
219
229
|
# Download the entire org skipping the billing admins group ACL and the group itself
|
220
|
-
chef_fs_config = ::ChefFS::Config.new
|
230
|
+
chef_fs_config = Chef::ChefFS::Config.new
|
221
231
|
top_level_paths = chef_fs_config.chef_fs.children.select { |entry| entry.name != 'acls' && entry.name != 'groups' }.map { |entry| entry.path }
|
222
|
-
acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.chef_fs, ::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
|
223
|
-
group_acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.chef_fs, ::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
224
|
-
group_paths = ::ChefFS::FileSystem.list(chef_fs_config.chef_fs, ::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
232
|
+
acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.chef_fs, Chef::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
|
233
|
+
group_acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.chef_fs, Chef::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
234
|
+
group_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.chef_fs, Chef::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
225
235
|
(top_level_paths + group_acl_paths + acl_paths + group_paths).each do |path|
|
226
|
-
::ChefFS::FileSystem.copy_to(::ChefFS::FilePattern.new(path), chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
236
|
+
Chef::ChefFS::FileSystem.copy_to(Chef::ChefFS::FilePattern.new(path), chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
227
237
|
end
|
228
238
|
|
229
239
|
ensure
|
230
|
-
|
231
|
-
Chef::Config[key.to_sym] = old_config[key]
|
232
|
-
end
|
240
|
+
Chef::Config.restore(old_config)
|
233
241
|
end
|
234
242
|
end
|
235
243
|
end
|
@@ -52,8 +52,9 @@ class Chef
|
|
52
52
|
|
53
53
|
def db
|
54
54
|
@db ||= begin
|
55
|
+
require 'sequel'
|
55
56
|
server_string = "#{config[:sql_user]}:#{config[:sql_password]}@#{config[:sql_host]}:#{config[:sql_port]}/opscode_chef"
|
56
|
-
Sequel.connect("postgres://#{server_string}")
|
57
|
+
::Sequel.connect("postgres://#{server_string}")
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
@@ -37,7 +37,7 @@ class Chef
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def export(path)
|
40
|
-
users = db.select(:username, :public_key, :pubkey_version, :hashed_password, :salt, :hash_type).from(:users)
|
40
|
+
users = db.select(:username, :id, :public_key, :pubkey_version, :hashed_password, :salt, :hash_type).from(:users)
|
41
41
|
File.open(path, 'w') { |file| file.write(users.all.to_json) }
|
42
42
|
end
|
43
43
|
end
|
@@ -33,6 +33,12 @@ class Chef
|
|
33
33
|
:boolean => true,
|
34
34
|
:description => "Upload pivotal key. By default the pivotal key is not uploaded."
|
35
35
|
|
36
|
+
option :skip_ids,
|
37
|
+
:long => "--[no-]skip-user-ids",
|
38
|
+
:default => true,
|
39
|
+
:boolean => true,
|
40
|
+
:description => "Upload user ids."
|
41
|
+
|
36
42
|
def run
|
37
43
|
if config[:sql_user].nil? || config[:sql_password].nil?
|
38
44
|
load_config_from_file!
|
@@ -46,6 +52,7 @@ class Chef
|
|
46
52
|
def import(path)
|
47
53
|
key_data = JSON.parse(File.read(path))
|
48
54
|
key_data.each do |d|
|
55
|
+
id = d['id']
|
49
56
|
username = d['username']
|
50
57
|
key = d['public_key']
|
51
58
|
version = d['pubkey_version']
|
@@ -63,11 +70,14 @@ class Chef
|
|
63
70
|
if users_to_update.count != 1
|
64
71
|
ui.warn "Wrong number of users to update for #{username}. Skipping"
|
65
72
|
else
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
73
|
+
data = { :public_key => key,
|
74
|
+
:pubkey_version => version,
|
75
|
+
:salt => salt,
|
76
|
+
:hashed_password => hashed_password,
|
77
|
+
:hash_type => hash_type
|
78
|
+
}
|
79
|
+
data[:id] = id unless config[:skip_ids]
|
80
|
+
users_to_update.update(data)
|
71
81
|
end
|
72
82
|
end
|
73
83
|
end
|
@@ -31,22 +31,36 @@ class Chef
|
|
31
31
|
:default => false,
|
32
32
|
:description => "Whether to skip checking the Chef Server version. This will also skip any auto-configured options"
|
33
33
|
|
34
|
+
option :org,
|
35
|
+
:long => "--only-org ORG",
|
36
|
+
:description => "Only restore objects in the named organization (default: all orgs)"
|
37
|
+
|
38
|
+
option :skip_users,
|
39
|
+
:long => "--skip-users",
|
40
|
+
:description => "Skip restoring users"
|
41
|
+
|
42
|
+
option :with_user_sql,
|
43
|
+
:long => "--with-user-sql",
|
44
|
+
:description => "Restore user id's, passwords, and keys from sql export"
|
45
|
+
|
34
46
|
deps do
|
35
47
|
require 'chef/json_compat'
|
36
|
-
require 'chef_fs/config'
|
37
|
-
require 'chef_fs/file_system'
|
38
|
-
require 'chef_fs/file_pattern'
|
39
|
-
|
40
|
-
require 'chef_fs/
|
48
|
+
require 'chef/chef_fs/config'
|
49
|
+
require 'chef/chef_fs/file_system'
|
50
|
+
require 'chef/chef_fs/file_pattern'
|
51
|
+
# Work around bug in chef_fs
|
52
|
+
require 'chef/chef_fs/command_line'
|
53
|
+
require 'chef/chef_fs/file_system/acl_entry'
|
54
|
+
require 'chef/chef_fs/data_handler/acl_data_handler'
|
41
55
|
require 'securerandom'
|
42
|
-
require 'chef_fs/parallelizer'
|
56
|
+
require 'chef/chef_fs/parallelizer'
|
43
57
|
require 'chef/tsorter'
|
44
58
|
end
|
45
59
|
|
46
60
|
def configure_chef
|
47
61
|
super
|
48
62
|
Chef::Config[:concurrency] = config[:concurrency].to_i if config[:concurrency]
|
49
|
-
::ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
|
63
|
+
Chef::ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
|
50
64
|
end
|
51
65
|
|
52
66
|
def run
|
@@ -109,46 +123,22 @@ class Chef
|
|
109
123
|
config[:skip_useracl] = true
|
110
124
|
user_acl_rest = nil
|
111
125
|
else
|
112
|
-
user_acl_rest = rest
|
113
|
-
end
|
126
|
+
user_acl_rest = rest
|
127
|
+
end
|
114
128
|
else
|
115
129
|
ui.warn("Unable to detect Chef Server version.")
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
119
|
-
# Restore users
|
120
|
-
puts "Restoring users ..."
|
121
|
-
|
122
133
|
rest = Chef::REST.new(Chef::Config.chef_server_root)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
name = $1
|
127
|
-
if name == 'pivotal' && !config[:overwrite_pivotal]
|
128
|
-
ui.warn("Skipping pivotal update. To overwrite pivotal, pass --overwrite-pivotal.")
|
129
|
-
next
|
130
|
-
end
|
131
|
-
|
132
|
-
# Update user object
|
133
|
-
user = JSONCompat.from_json(IO.read("#{dest_dir}/users/#{name}.json"))
|
134
|
-
begin
|
135
|
-
# Supply password for new user
|
136
|
-
user_with_password = user.dup
|
137
|
-
user_with_password['password'] = SecureRandom.hex
|
138
|
-
rest.post_rest('users', user_with_password)
|
139
|
-
rescue Net::HTTPServerException => e
|
140
|
-
if e.response.code == "409"
|
141
|
-
rest.put_rest("users/#{name}", user)
|
142
|
-
else
|
143
|
-
raise
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
134
|
+
# Restore users
|
135
|
+
restore_users(dest_dir, rest) unless config[:skip_users]
|
136
|
+
restore_user_sql(dest_dir) if config[:with_user_sql]
|
148
137
|
|
149
138
|
# Restore organizations
|
150
139
|
Dir.foreach("#{dest_dir}/organizations") do |name|
|
151
140
|
next if name == '..' || name == '.' || !File.directory?("#{dest_dir}/organizations/#{name}")
|
141
|
+
next unless (config[:org].nil? || config[:org] == name)
|
152
142
|
puts "Restoring org #{name} ..."
|
153
143
|
|
154
144
|
# Create organization
|
@@ -170,7 +160,7 @@ class Chef
|
|
170
160
|
rest.post_rest("organizations/#{name}/association_requests", { 'user' => invitation['username'] })
|
171
161
|
rescue Net::HTTPServerException => e
|
172
162
|
if e.response.code != "409"
|
173
|
-
|
163
|
+
ui.error("Cannot create invitation #{invitation['id']}")
|
174
164
|
end
|
175
165
|
end
|
176
166
|
end
|
@@ -210,7 +200,7 @@ class Chef
|
|
210
200
|
|
211
201
|
# Update user acl
|
212
202
|
user_acl = JSONCompat.from_json(IO.read("#{dest_dir}/user_acls/#{name}.json"))
|
213
|
-
put_acl(rest, "users/#{name}/_acl", user_acl)
|
203
|
+
put_acl(rest, "users/#{name}/_acl", user_acl)
|
214
204
|
end
|
215
205
|
|
216
206
|
|
@@ -219,18 +209,54 @@ class Chef
|
|
219
209
|
end
|
220
210
|
end
|
221
211
|
|
212
|
+
def restore_users(dest_dir, rest)
|
213
|
+
puts "Restoring users ..."
|
214
|
+
Dir.foreach("#{dest_dir}/users") do |filename|
|
215
|
+
next if filename !~ /(.+)\.json/
|
216
|
+
name = $1
|
217
|
+
if name == 'pivotal' && !config[:overwrite_pivotal]
|
218
|
+
ui.warn("Skipping pivotal update. To overwrite pivotal, pass --overwrite-pivotal.")
|
219
|
+
next
|
220
|
+
end
|
221
|
+
|
222
|
+
# Update user object
|
223
|
+
user = JSONCompat.from_json(IO.read("#{dest_dir}/users/#{name}.json"))
|
224
|
+
begin
|
225
|
+
# Supply password for new user
|
226
|
+
user_with_password = user.dup
|
227
|
+
user_with_password['password'] = SecureRandom.hex
|
228
|
+
rest.post_rest('users', user_with_password)
|
229
|
+
rescue Net::HTTPServerException => e
|
230
|
+
if e.response.code == "409"
|
231
|
+
rest.put_rest("users/#{name}", user)
|
232
|
+
else
|
233
|
+
raise
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def restore_user_sql(dest_dir)
|
240
|
+
require 'chef/knife/ec_key_import'
|
241
|
+
k = Chef::Knife::EcKeyImport.new
|
242
|
+
k.name_args = ["#{dest_dir}/key_dump.json"]
|
243
|
+
k.config[:skip_pivotal] = true
|
244
|
+
k.config[:skip_ids] = false
|
245
|
+
k.config[:sql_host] = "localhost"
|
246
|
+
k.config[:sql_port] = 5432
|
247
|
+
k.run
|
248
|
+
end
|
249
|
+
|
222
250
|
PATHS = %w(chef_repo_path cookbook_path environment_path data_bag_path role_path node_path client_path acl_path group_path container_path)
|
223
|
-
CONFIG_VARS = %w(chef_server_url chef_server_root custom_http_headers node_name client_key versioned_cookbooks) + PATHS
|
224
251
|
def upload_org(dest_dir, webui_key, name)
|
225
|
-
old_config =
|
226
|
-
|
227
|
-
old_config[key] = Chef::Config[key.to_sym]
|
228
|
-
end
|
252
|
+
old_config = Chef::Config.save
|
253
|
+
|
229
254
|
begin
|
230
255
|
# Clear out paths
|
231
|
-
PATHS.each do |
|
232
|
-
Chef::Config
|
256
|
+
PATHS.each do |path|
|
257
|
+
Chef::Config.delete(path.to_sym)
|
233
258
|
end
|
259
|
+
|
234
260
|
Chef::Config.chef_repo_path = "#{dest_dir}/organizations/#{name}"
|
235
261
|
Chef::Config.versioned_cookbooks = true
|
236
262
|
|
@@ -238,15 +264,15 @@ class Chef
|
|
238
264
|
|
239
265
|
# Upload the admins group and billing-admins acls
|
240
266
|
puts "Restoring the org admin data"
|
241
|
-
chef_fs_config = ::ChefFS::Config.new
|
267
|
+
chef_fs_config = Chef::ChefFS::Config.new
|
242
268
|
|
243
269
|
# Restore users w/o clients (which don't exist yet)
|
244
270
|
['admins', 'billing-admins'].each do |group|
|
245
271
|
restore_group(chef_fs_config, group, :clients => false)
|
246
272
|
end
|
247
273
|
|
248
|
-
pattern = ::ChefFS::FilePattern.new('/acls/groups/billing-admins.json')
|
249
|
-
if ::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.local_fs, chef_fs_config.chef_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
274
|
+
pattern = Chef::ChefFS::FilePattern.new('/acls/groups/billing-admins.json')
|
275
|
+
if Chef::ChefFS::FileSystem.copy_to(pattern, chef_fs_config.local_fs, chef_fs_config.chef_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
250
276
|
@error = true
|
251
277
|
end
|
252
278
|
|
@@ -267,30 +293,28 @@ class Chef
|
|
267
293
|
|
268
294
|
# Restore the entire org skipping the admin data and restoring groups and acls last
|
269
295
|
puts "Restoring the rest of the org"
|
270
|
-
chef_fs_config = ::ChefFS::Config.new
|
296
|
+
chef_fs_config = Chef::ChefFS::Config.new
|
271
297
|
top_level_paths = chef_fs_config.local_fs.children.select { |entry| entry.name != 'acls' && entry.name != 'groups' }.map { |entry| entry.path }
|
272
298
|
|
273
299
|
# Topologically sort groups for upload
|
274
|
-
unsorted_groups = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| JSON.parse(entry.read) }
|
300
|
+
unsorted_groups = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| JSON.parse(entry.read) }
|
275
301
|
group_paths = sort_groups_for_upload(unsorted_groups).map { |group_name| "/groups/#{group_name}.json" }
|
276
302
|
|
277
|
-
group_acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
278
|
-
acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
|
303
|
+
group_acl_paths = Chef::ChefFS::FileSystem.list(chef_fs_config.local_fs, Chef::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
|
304
|
+
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 }
|
279
305
|
|
280
306
|
(top_level_paths + group_paths + group_acl_paths + acl_paths).each do |path|
|
281
|
-
::ChefFS::FileSystem.copy_to(::ChefFS::FilePattern.new(path), chef_fs_config.local_fs, chef_fs_config.chef_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
307
|
+
Chef::ChefFS::FileSystem.copy_to(Chef::ChefFS::FilePattern.new(path), chef_fs_config.local_fs, chef_fs_config.chef_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
|
282
308
|
end
|
283
309
|
# restore clients to groups, using the pivotal key again
|
284
310
|
Chef::Config[:node_name] = old_config['node_name']
|
285
|
-
Chef::Config[:client_key] = old_config['client_key']
|
311
|
+
Chef::Config[:client_key] = old_config['client_key']
|
286
312
|
Chef::Config.custom_http_headers = {}
|
287
313
|
['admins', 'billing-admins'].each do |group|
|
288
|
-
restore_group(::ChefFS::Config.new, group)
|
314
|
+
restore_group(Chef::ChefFS::Config.new, group)
|
289
315
|
end
|
290
316
|
ensure
|
291
|
-
|
292
|
-
Chef::Config[key.to_sym] = old_config[key]
|
293
|
-
end
|
317
|
+
Chef::Config.restore(old_config)
|
294
318
|
end
|
295
319
|
end
|
296
320
|
|
@@ -316,13 +340,13 @@ class Chef
|
|
316
340
|
def restore_group(chef_fs_config, group_name, includes = {:users => true, :clients => true})
|
317
341
|
includes[:users] = true unless includes.key? :users
|
318
342
|
includes[:clients] = true unless includes.key? :clients
|
319
|
-
|
320
|
-
group = ::ChefFS::FileSystem.resolve_path(
|
343
|
+
|
344
|
+
group = Chef::ChefFS::FileSystem.resolve_path(
|
321
345
|
chef_fs_config.chef_fs,
|
322
346
|
"/groups/#{group_name}.json"
|
323
347
|
)
|
324
348
|
|
325
|
-
members_json = ::ChefFS::FileSystem.resolve_path(
|
349
|
+
members_json = Chef::ChefFS::FileSystem.resolve_path(
|
326
350
|
chef_fs_config.local_fs,
|
327
351
|
"/groups/#{group_name}.json"
|
328
352
|
).read
|
@@ -336,20 +360,20 @@ class Chef
|
|
336
360
|
member == 'clients'
|
337
361
|
end
|
338
362
|
end
|
339
|
-
|
363
|
+
|
340
364
|
group.write(members.to_json)
|
341
365
|
end
|
342
366
|
|
343
367
|
def parallelize(entries, options = {}, &block)
|
344
|
-
::ChefFS::Parallelizer.parallelize(entries, options, &block)
|
368
|
+
Chef::ChefFS::Parallelizer.parallelize(entries, options, &block)
|
345
369
|
end
|
346
370
|
|
347
371
|
def put_acl(rest, url, acls)
|
348
372
|
old_acls = rest.get_rest(url)
|
349
|
-
old_acls = ::ChefFS::DataHandler::AclDataHandler.new.normalize(old_acls, nil)
|
350
|
-
acls = ::ChefFS::DataHandler::AclDataHandler.new.normalize(acls, nil)
|
373
|
+
old_acls = Chef::ChefFS::DataHandler::AclDataHandler.new.normalize(old_acls, nil)
|
374
|
+
acls = Chef::ChefFS::DataHandler::AclDataHandler.new.normalize(acls, nil)
|
351
375
|
if acls != old_acls
|
352
|
-
::ChefFS::FileSystem::AclEntry::PERMISSIONS.each do |permission|
|
376
|
+
Chef::ChefFS::FileSystem::AclEntry::PERMISSIONS.each do |permission|
|
353
377
|
rest.put_rest("#{url}/#{permission}", { permission => acls[permission] })
|
354
378
|
end
|
355
379
|
end
|
metadata
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-ec-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: sequel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: chef
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '11.8'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '11.8'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,12 +113,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
113
|
version: '0'
|
114
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- - "
|
116
|
+
- - ">"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version:
|
118
|
+
version: 1.3.1
|
119
119
|
requirements: []
|
120
120
|
rubyforge_project:
|
121
|
-
rubygems_version: 2.2.
|
121
|
+
rubygems_version: 2.2.2
|
122
122
|
signing_key:
|
123
123
|
specification_version: 4
|
124
124
|
summary: Backup and Restore of Enterprise Chef
|