knife-ec-backup 0.9.6 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +108 -0
- data/lib/chef/knife/ec_backup.rb +19 -8
- data/lib/chef/knife/ec_restore.rb +31 -7
- data/lib/knife_ec_backup/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80ef809cf9b6913773b6359560563034d86afed2
|
4
|
+
data.tar.gz: e2daaccc75106518a75e027c87d37df7c4e0ca55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55efc9670ec8899eb1940fbaa88b92becbed3c4fd1c0377385873892740da213389ceca8d82f60f8b36b83d662ee6518bc66c15a71951cc01596013c4a23e9b2
|
7
|
+
data.tar.gz: 65dc9db1074a0c2997e7390224abae16c9264c72bf61ff0c3379ce05f2012ee60907708a6f03bb32f09f8bcc6de0efdfb6098a7ff20fca4d37a79dfb51f43542
|
data/README.md
CHANGED
@@ -0,0 +1,108 @@
|
|
1
|
+
# knife EC backup
|
2
|
+
|
3
|
+
# Description
|
4
|
+
|
5
|
+
This is an UNOFFICIAL and EXPERIMENTAL knife plugin intended to back up and restore an entire Enterprise Chef / Private Chef server, preserving the data in an intermediate, editable text format.
|
6
|
+
|
7
|
+
# Installation
|
8
|
+
|
9
|
+
This knife plugin is packaged as a gem. To install it, clone the
|
10
|
+
git repository and run the following:
|
11
|
+
|
12
|
+
gem build knife-ec-backup.gemspec
|
13
|
+
gem install knife-ec-backup-0.9.6.gem
|
14
|
+
|
15
|
+
# Configuration
|
16
|
+
|
17
|
+
## knife.rb
|
18
|
+
Unlike other knife subcommands the subcommands in the knife-ec-backup plugin make API calls against the root of your EC installations API endpoint.
|
19
|
+
|
20
|
+
Typically the chef_server_url for your OPC installation may look like this:
|
21
|
+
|
22
|
+
chef_server_url https://chef.yourdomain.com/organizations/ORGNAME
|
23
|
+
|
24
|
+
To configure knife-ec-backup, set the `chef_server_root` option to the root of your OPC installation:
|
25
|
+
|
26
|
+
chef_server_root https://chef.yourdomain.com/
|
27
|
+
|
28
|
+
Note that most users in an EC installation lack the permissions to pull most of the data from all organizations and other users.
|
29
|
+
|
30
|
+
# Subcommands
|
31
|
+
|
32
|
+
## knife ec backup DEST_DIR WEBUI_KEY \[USER_ACL_REST\] (options)
|
33
|
+
|
34
|
+
*Options*
|
35
|
+
|
36
|
+
* `--concurrency`:
|
37
|
+
Maximum number of simultaneous requests to send (default: 10)
|
38
|
+
* `--skip-useracl`:
|
39
|
+
Whether to skip downloading User ACLs. This is required for EC 11.0.0 and lower (default: false)
|
40
|
+
|
41
|
+
Creates a repository of an entire Enterprise Chef / Private Chef server.
|
42
|
+
|
43
|
+
The format of the repository is based on the `knife-essentials` (`knife download`) format and looks like this:
|
44
|
+
|
45
|
+
users
|
46
|
+
<name>.json
|
47
|
+
user_acls
|
48
|
+
<name>.json
|
49
|
+
organizations
|
50
|
+
<orgname>
|
51
|
+
acls
|
52
|
+
<type>
|
53
|
+
<name>.json
|
54
|
+
clients
|
55
|
+
<name>.json
|
56
|
+
containers
|
57
|
+
<name>.json
|
58
|
+
cookbooks
|
59
|
+
<name>-<version>
|
60
|
+
data_bags
|
61
|
+
<bag name>
|
62
|
+
<item name>
|
63
|
+
environments
|
64
|
+
<name>.json
|
65
|
+
groups
|
66
|
+
<name>.json
|
67
|
+
nodes
|
68
|
+
<name>.json
|
69
|
+
roles
|
70
|
+
<name>.json
|
71
|
+
org.json
|
72
|
+
members.json
|
73
|
+
invitations.json
|
74
|
+
|
75
|
+
This compares very closely with the "knife download /" from an OSC server:
|
76
|
+
|
77
|
+
clients
|
78
|
+
<name>.json
|
79
|
+
cookbooks
|
80
|
+
<name>-<version>
|
81
|
+
data_bags
|
82
|
+
<bag name>
|
83
|
+
<item name>
|
84
|
+
environments
|
85
|
+
<name>.json
|
86
|
+
nodes
|
87
|
+
<name>.json
|
88
|
+
roles
|
89
|
+
<name>.json
|
90
|
+
users
|
91
|
+
<name>.json>
|
92
|
+
|
93
|
+
## knife ec restore DEST_DIR WEBUI_KEY \[USER_ACL_REST\] (options)
|
94
|
+
|
95
|
+
*Options*
|
96
|
+
|
97
|
+
* `--concurrency`:
|
98
|
+
Maximum number of simultaneous requests to send (default: 10)
|
99
|
+
* `--overwrite-pivotal`:
|
100
|
+
Whether to overwrite pivotal's key. Once this is done, future requests will fail until you fix the private key (default: false)
|
101
|
+
* `--skip-useracl`:
|
102
|
+
Whether to skip downloading User ACLs. This is required for EC 11.0.0 and lower (default: false)
|
103
|
+
|
104
|
+
Restores all data from a repository to an Enterprise Chef / Private Chef server.
|
105
|
+
|
106
|
+
# TODO
|
107
|
+
|
108
|
+
* Prevent 403 error for Billing Admins ACL as it is downloaded in another method.
|
data/lib/chef/knife/ec_backup.rb
CHANGED
@@ -9,6 +9,12 @@ class Chef
|
|
9
9
|
:long => '--concurrency THREADS',
|
10
10
|
:description => 'Maximum number of simultaneous requests to send (default: 10)'
|
11
11
|
|
12
|
+
option :skip_useracl,
|
13
|
+
:long => '--skip-useracl',
|
14
|
+
:boolean => true,
|
15
|
+
:default => false,
|
16
|
+
:description => "Whether to skip downloading User ACLs. This is required for EC 11.0.0 and lower"
|
17
|
+
|
12
18
|
deps do
|
13
19
|
require 'chef_fs/config'
|
14
20
|
require 'chef_fs/file_system'
|
@@ -30,7 +36,7 @@ class Chef
|
|
30
36
|
|
31
37
|
dest_dir = name_args[0]
|
32
38
|
webui_key = name_args[1]
|
33
|
-
rest = Chef::REST.new(Chef::Config.
|
39
|
+
rest = Chef::REST.new(Chef::Config.chef_server_root)
|
34
40
|
if name_args.length >= 3
|
35
41
|
user_acl_rest = Chef::REST.new(name_args[2])
|
36
42
|
else
|
@@ -46,6 +52,12 @@ class Chef
|
|
46
52
|
File.open("#{dest_dir}/users/#{name}.json", 'w') do |file|
|
47
53
|
file.write(Chef::JSONCompat.to_json_pretty(rest.get_rest(url)))
|
48
54
|
end
|
55
|
+
|
56
|
+
if config[:skip_useracl]
|
57
|
+
ui.warn("Skipping user ACL download for #{name}. To download this ACL, remove --skip-useracl.")
|
58
|
+
next
|
59
|
+
end
|
60
|
+
|
49
61
|
File.open("#{dest_dir}/user_acls/#{name}.json", 'w') do |file|
|
50
62
|
file.write(Chef::JSONCompat.to_json_pretty(user_acl_rest.get_rest("users/#{name}/_acl")))
|
51
63
|
end
|
@@ -83,7 +95,7 @@ class Chef
|
|
83
95
|
end
|
84
96
|
|
85
97
|
PATHS = %w(chef_repo_path cookbook_path environment_path data_bag_path role_path node_path client_path acl_path group_path container_path)
|
86
|
-
CONFIG_VARS = %w(chef_server_url custom_http_headers node_name client_key) + PATHS
|
98
|
+
CONFIG_VARS = %w(chef_server_url chef_server_root custom_http_headers node_name client_key versioned_cookbooks) + PATHS
|
87
99
|
def download_org(dest_dir, webui_key, name)
|
88
100
|
old_config = {}
|
89
101
|
CONFIG_VARS.each do |key|
|
@@ -95,18 +107,17 @@ class Chef
|
|
95
107
|
Chef::Config[path_var.to_sym] = nil
|
96
108
|
end
|
97
109
|
Chef::Config.chef_repo_path = "#{dest_dir}/organizations/#{name}"
|
110
|
+
Chef::Config.versioned_cookbooks = true
|
98
111
|
|
99
|
-
Chef::Config.chef_server_url = "#{Chef::Config.
|
112
|
+
Chef::Config.chef_server_url = "#{Chef::Config.chef_server_root}/organizations/#{name}"
|
100
113
|
|
101
114
|
ensure_dir(Chef::Config.chef_repo_path)
|
102
115
|
|
103
116
|
# Download the billing-admins acls as pivotal
|
104
117
|
chef_fs_config = ::ChefFS::Config.new
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
@error = true
|
109
|
-
end
|
118
|
+
pattern = ::ChefFS::FilePattern.new('/acls/groups/billing-admins.json')
|
119
|
+
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) })
|
120
|
+
@error = true
|
110
121
|
end
|
111
122
|
|
112
123
|
# Figure out who the admin is so we can spoof him and retrieve his stuff
|
@@ -15,6 +15,13 @@ class Chef
|
|
15
15
|
:default => false,
|
16
16
|
:description => "Whether to overwrite pivotal's key. Once this is done, future requests will fail until you fix the private key."
|
17
17
|
|
18
|
+
option :skip_useracl,
|
19
|
+
:long => '--skip-useracl',
|
20
|
+
:boolean => true,
|
21
|
+
:default => false,
|
22
|
+
:description => "Whether to skip restoring User ACLs. This is required for EC 11.0.2 and lower"
|
23
|
+
|
24
|
+
|
18
25
|
deps do
|
19
26
|
require 'chef/json_compat'
|
20
27
|
require 'chef_fs/config'
|
@@ -40,7 +47,7 @@ class Chef
|
|
40
47
|
|
41
48
|
dest_dir = name_args[0]
|
42
49
|
webui_key = name_args[1]
|
43
|
-
rest = Chef::REST.new(Chef::Config.
|
50
|
+
rest = Chef::REST.new(Chef::Config.chef_server_root)
|
44
51
|
if name_args.length >= 3
|
45
52
|
user_acl_rest = Chef::REST.new(name_args[2])
|
46
53
|
else
|
@@ -72,10 +79,6 @@ class Chef
|
|
72
79
|
end
|
73
80
|
end
|
74
81
|
|
75
|
-
# Update user acl
|
76
|
-
# Doesn't work at present due to server
|
77
|
-
#user_acl = JSONCompat.from_json(IO.read("#{dest_dir}/user_acls/#{name}.json"))
|
78
|
-
#put_acl(user_acl_rest, "users/#{name}/_acl", user_acl)
|
79
82
|
end
|
80
83
|
|
81
84
|
# Restore organizations
|
@@ -126,13 +129,33 @@ class Chef
|
|
126
129
|
upload_org(dest_dir, webui_key, name)
|
127
130
|
end
|
128
131
|
|
132
|
+
# Restore user ACLs
|
133
|
+
puts "Restoring user ACLs ..."
|
134
|
+
Dir.foreach("#{dest_dir}/users") do |filename|
|
135
|
+
next if filename !~ /(.+)\.json/
|
136
|
+
name = $1
|
137
|
+
if config[:skip_useracl]
|
138
|
+
ui.warn("Skipping user ACL update for #{name}. To update this ACL, remove --skip-useracl.")
|
139
|
+
next
|
140
|
+
end
|
141
|
+
if name == 'pivotal' && !config[:overwrite_pivotal]
|
142
|
+
ui.warn("Skipping pivotal update. To overwrite pivotal, pass --overwrite-pivotal. Once pivotal is updated, you will need to modify #{Chef::Config.client_key} to be the corresponding private key.")
|
143
|
+
next
|
144
|
+
end
|
145
|
+
|
146
|
+
# Update user acl
|
147
|
+
user_acl = JSONCompat.from_json(IO.read("#{dest_dir}/user_acls/#{name}.json"))
|
148
|
+
put_acl(user_acl_rest, "users/#{name}/_acl", user_acl)
|
149
|
+
end
|
150
|
+
|
151
|
+
|
129
152
|
if @error
|
130
153
|
exit 1
|
131
154
|
end
|
132
155
|
end
|
133
156
|
|
134
157
|
PATHS = %w(chef_repo_path cookbook_path environment_path data_bag_path role_path node_path client_path acl_path group_path container_path)
|
135
|
-
CONFIG_VARS = %w(chef_server_url custom_http_headers node_name client_key) + PATHS
|
158
|
+
CONFIG_VARS = %w(chef_server_url chef_server_root custom_http_headers node_name client_key versioned_cookbooks) + PATHS
|
136
159
|
def upload_org(dest_dir, webui_key, name)
|
137
160
|
old_config = {}
|
138
161
|
CONFIG_VARS.each do |key|
|
@@ -144,8 +167,9 @@ class Chef
|
|
144
167
|
Chef::Config[path_var.to_sym] = nil
|
145
168
|
end
|
146
169
|
Chef::Config.chef_repo_path = "#{dest_dir}/organizations/#{name}"
|
170
|
+
Chef::Config.versioned_cookbooks = true
|
147
171
|
|
148
|
-
Chef::Config.chef_server_url = "#{Chef::Config.
|
172
|
+
Chef::Config.chef_server_url = "#{Chef::Config.chef_server_root}/organizations/#{name}"
|
149
173
|
|
150
174
|
# Upload the admins group and billing-admins acls
|
151
175
|
chef_fs_config = ::ChefFS::Config.new
|
@@ -1,3 +1,3 @@
|
|
1
1
|
module KnifeECBackup
|
2
|
-
VERSION = '0
|
3
|
-
end
|
2
|
+
VERSION = '1.0'
|
3
|
+
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: 0
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10
|
11
|
+
date: 2013-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|