knife-backup 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -3
- data/knife-backup.gemspec +1 -0
- data/lib/chef/knife/backup_export.rb +36 -11
- data/lib/chef/knife/backup_restore.rb +37 -10
- data/lib/knife-backup/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d3d0c4ce95fad2034a86fbb959ab937635477f6
|
4
|
+
data.tar.gz: 5b3efc672de9d874b178212b792eb8e56adbec2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66784ee08a6503ce04f3ad39b9415cd55820b85ea06ad520c1bf8a5330041d4e17765f54fbcc3046f403e633cf7c52a3d68613ecf8a577642f167ac90d24c49b
|
7
|
+
data.tar.gz: fd0b5a409ba37a128d17bed4a51c3cb12b033cd4f1ae57fe8457ae0295687bf4ba6ceec12aa9ee30c1a9b2e3502eb85215e4f78ce20d93dc2c41c37e5c78fd25
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@ Knife-Backup
|
|
4
4
|
Knife-Backup is a [Knife](http://wiki.opscode.com/display/chef/Knife) plugin that can help you backup and restore a chef server. It is based on the great work of [Steven Danna][stevendanna] and [Joshua Timberman][jtimberman] on the [BackupExport][backup_export] and [BackupRestore][backup_restore] plugins. Currently knife-backup has support for the following objects:
|
5
5
|
|
6
6
|
* clients
|
7
|
+
* users (chef >= 11)
|
7
8
|
* nodes
|
8
9
|
* roles
|
9
10
|
* environments
|
@@ -12,6 +13,8 @@ Knife-Backup is a [Knife](http://wiki.opscode.com/display/chef/Knife) plugin tha
|
|
12
13
|
|
13
14
|
knife-backup will backup all cookbook versions available on the chef server. Cookbooks are normally available in a repository and should be easy to upload like that, but if you are using various cookbook versions in each environment then it might not be so trivial to find and upload them back to the server; downloading them and having them available to upload like that is simple and clean. If you have too many cookbook [versions](http://www.ducea.com/2013/02/26/knife-cleanup/) then you might want to cleanup them first using something like [knife-cleanup][knifecleanup]
|
14
15
|
|
16
|
+
Users are a bit tricky, knife-backup can't gather the crypted passwords via the chef server so it's forced to reset them to a random string on restore. Be sure to copy them from the restore output or reset them.
|
17
|
+
|
15
18
|
*Known limitation*: currently it is not possible to overwritte a client object already available on the target server and these will be skipped.
|
16
19
|
|
17
20
|
## Installation
|
@@ -33,8 +36,11 @@ knife backup --help
|
|
33
36
|
Currently the available commands are:
|
34
37
|
|
35
38
|
```bash
|
36
|
-
knife backup export [-D DIR]
|
37
|
-
knife backup restore [-D DIR]
|
39
|
+
knife backup export [component component ...] [-D DIR]
|
40
|
+
knife backup restore [component component ...] [-D DIR]
|
41
|
+
|
42
|
+
#Example:
|
43
|
+
knife backup export cookbooks roles environments -D ~/my_chef_backup
|
38
44
|
```
|
39
45
|
|
40
46
|
Note: you should treat this as beta software; I'm using it with success for my needs and hopefully you will find it useful too.
|
@@ -42,7 +48,6 @@ Note: you should treat this as beta software; I'm using it with success for my n
|
|
42
48
|
## Todo/Ideas
|
43
49
|
|
44
50
|
* Timestamp for the backup folder
|
45
|
-
* Limit the backup to just some objects (for ex, just backup the cookbooks or just the nodes)
|
46
51
|
* Track the failed downloads and report them at the end
|
47
52
|
* Find out if there is a way to overwrite a client object.
|
48
53
|
|
data/knife-backup.gemspec
CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "https://github.com/mdxp/knife-backup"
|
11
11
|
s.summary = %q{Chef knife plugins to help backup and restore chef servers}
|
12
12
|
s.description = s.summary
|
13
|
+
s.license = "Apache 2.0"
|
13
14
|
|
14
15
|
s.rubyforge_project = "knife-backup"
|
15
16
|
|
@@ -19,6 +19,9 @@
|
|
19
19
|
|
20
20
|
require 'chef/node'
|
21
21
|
require 'chef/api_client'
|
22
|
+
if Chef::VERSION =~ /^1[1-9]\./
|
23
|
+
require 'chef/user'
|
24
|
+
end
|
22
25
|
require 'chef/knife/cookbook_download'
|
23
26
|
|
24
27
|
module ServerBackup
|
@@ -32,16 +35,16 @@ module ServerBackup
|
|
32
35
|
banner "knife backup export [COMPONENT [COMPONENT ...]] [-D DIR] (options)"
|
33
36
|
|
34
37
|
option :backup_dir,
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
:short => "-D DIR",
|
39
|
+
:long => "--backup-directory DIR",
|
40
|
+
:description => "Store backup data in DIR. DIR will be created if it does not already exist.",
|
41
|
+
:default => Chef::Config[:knife][:chef_server_backup_dir] ? Chef::Config[:knife][:chef_server_backup_dir] : File.join(".chef", "chef_server_backup")
|
39
42
|
|
40
43
|
option :latest,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
:short => "-N",
|
45
|
+
:long => "--latest",
|
46
|
+
:description => "The version of the cookbook to download",
|
47
|
+
:boolean => true
|
45
48
|
|
46
49
|
def run
|
47
50
|
validate!
|
@@ -50,7 +53,8 @@ module ServerBackup
|
|
50
53
|
end
|
51
54
|
|
52
55
|
private
|
53
|
-
COMPONENTS = %w(clients nodes roles data_bags environments cookbooks)
|
56
|
+
COMPONENTS = %w(clients users nodes roles data_bags environments cookbooks)
|
57
|
+
LOAD_TRIES = 5
|
54
58
|
|
55
59
|
def validate!
|
56
60
|
bad_names = name_args - COMPONENTS
|
@@ -68,6 +72,14 @@ module ServerBackup
|
|
68
72
|
backup_standard("clients", Chef::ApiClient)
|
69
73
|
end
|
70
74
|
|
75
|
+
def users
|
76
|
+
if Chef::VERSION =~ /^1[1-9]\./
|
77
|
+
backup_standard("users", Chef::User)
|
78
|
+
else
|
79
|
+
ui.warn "users export only supported on chef >= 11"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
71
83
|
def roles
|
72
84
|
backup_standard("roles", Chef::Role)
|
73
85
|
end
|
@@ -99,14 +111,27 @@ module ServerBackup
|
|
99
111
|
klass.list.each do |component_name, url|
|
100
112
|
next if component == "environments" && component_name == "_default"
|
101
113
|
ui.msg "Backing up #{component} #{component_name}"
|
102
|
-
component_obj = klass
|
114
|
+
component_obj = load_object(klass, component_name)
|
115
|
+
unless component_obj
|
116
|
+
ui.error "Could not load #{klass} #{component_name}."
|
117
|
+
next
|
118
|
+
end
|
103
119
|
File.open(File.join(dir, "#{component_name}.json"), "w") do |component_file|
|
104
|
-
#component_file.print(component_obj.to_json)
|
105
120
|
component_file.print(JSON.pretty_generate(component_obj))
|
106
121
|
end
|
107
122
|
end
|
108
123
|
end
|
109
124
|
|
125
|
+
def load_object(klass, name, try = 1)
|
126
|
+
klass.load(name)
|
127
|
+
rescue NoMethodError
|
128
|
+
ui.warn "Problem loading #{klass} #{name}. Try #{try}/#{LOAD_TRIES}"
|
129
|
+
if try < LOAD_TRIES
|
130
|
+
try += 1
|
131
|
+
load_object(klass, name, try)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
110
135
|
def cookbooks
|
111
136
|
ui.msg "Backing up cookbooks"
|
112
137
|
dir = File.join(config[:backup_dir], "cookbooks")
|
@@ -32,15 +32,16 @@ module ServerBackup
|
|
32
32
|
require 'chef/knife/core/object_loader'
|
33
33
|
require 'chef/cookbook_uploader'
|
34
34
|
require 'chef/api_client'
|
35
|
+
require 'securerandom'
|
35
36
|
end
|
36
37
|
|
37
38
|
banner "knife backup restore [COMPONENT [COMPONENT ...]] [-D DIR] (options)"
|
38
39
|
|
39
40
|
option :backup_dir,
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
:short => "-D DIR",
|
42
|
+
:long => "--backup-directory DIR",
|
43
|
+
:description => "Restore backup data from DIR.",
|
44
|
+
:default => Chef::Config[:knife][:chef_server_backup_dir] ? Chef::Config[:knife][:chef_server_backup_dir] : File.join(".chef", "chef_server_backup")
|
44
45
|
|
45
46
|
def run
|
46
47
|
ui.warn "This will overwrite existing data!"
|
@@ -52,7 +53,7 @@ module ServerBackup
|
|
52
53
|
end
|
53
54
|
|
54
55
|
private
|
55
|
-
COMPONENTS = %w(clients nodes roles data_bags environments cookbooks)
|
56
|
+
COMPONENTS = %w(clients users nodes roles data_bags environments cookbooks)
|
56
57
|
|
57
58
|
def validate!
|
58
59
|
bad_names = name_args - COMPONENTS
|
@@ -129,24 +130,50 @@ module ServerBackup
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
133
|
+
def users
|
134
|
+
JSON.create_id = "no_thanks"
|
135
|
+
ui.info "=== Restoring users ==="
|
136
|
+
users = Dir.glob(File.join(config[:backup_dir], "users", "*.json"))
|
137
|
+
if !users.empty? and Chef::VERSION !~ /^1[1-9]\./
|
138
|
+
ui.warn "users restore only supported on chef >= 11"
|
139
|
+
return
|
140
|
+
end
|
141
|
+
users.each do |file|
|
142
|
+
user = JSON.parse(IO.read(file))
|
143
|
+
password = SecureRandom.hex[0..7]
|
144
|
+
begin
|
145
|
+
rest.post_rest("users", {
|
146
|
+
:name => user['name'],
|
147
|
+
:public_key => user['public_key'],
|
148
|
+
:admin => user['admin'],
|
149
|
+
:password => password
|
150
|
+
})
|
151
|
+
ui.info "Set password for #{user['name']} to #{password}, please update"
|
152
|
+
rescue Net::HTTPServerException => e
|
153
|
+
handle_error 'user', user['name'], e
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
132
158
|
def cookbooks
|
133
159
|
ui.info "=== Restoring cookbooks ==="
|
134
160
|
cookbooks = Dir.glob(File.join(config[:backup_dir], "cookbooks", '*'))
|
135
161
|
cookbooks.each do |cb|
|
136
|
-
full_cb =
|
137
|
-
|
138
|
-
|
162
|
+
full_cb = File.expand_path(cb)
|
163
|
+
cb_name = File.basename(cb)
|
164
|
+
cookbook = cb_name.reverse.split('-',2).last.reverse
|
165
|
+
full_path = File.join(File.dirname(full_cb), cookbook)
|
139
166
|
|
140
167
|
begin
|
141
168
|
File.symlink(full_cb, full_path)
|
142
169
|
cbu = Chef::Knife::CookbookUpload.new
|
143
170
|
Chef::Knife::CookbookUpload.load_deps
|
144
171
|
cbu.name_args = [ cookbook ]
|
145
|
-
cbu.config[:cookbook_path] = File.
|
172
|
+
cbu.config[:cookbook_path] = File.dirname(full_path)
|
146
173
|
ui.info "Restoring cookbook #{cbu.name_args}"
|
147
174
|
cbu.run
|
148
175
|
rescue Net::HTTPServerException => e
|
149
|
-
handle_error 'cookbook',
|
176
|
+
handle_error 'cookbook', cb_name, e
|
150
177
|
ensure
|
151
178
|
File.unlink(full_path)
|
152
179
|
end
|
data/lib/knife-backup/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marius Ducea
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -42,7 +42,8 @@ files:
|
|
42
42
|
- lib/knife-backup.rb
|
43
43
|
- lib/knife-backup/version.rb
|
44
44
|
homepage: https://github.com/mdxp/knife-backup
|
45
|
-
licenses:
|
45
|
+
licenses:
|
46
|
+
- Apache 2.0
|
46
47
|
metadata: {}
|
47
48
|
post_install_message:
|
48
49
|
rdoc_options: []
|