knife-ec-backup 0.9.6 → 1.0
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 +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
|