knife-ec-backup 1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80ef809cf9b6913773b6359560563034d86afed2
4
- data.tar.gz: e2daaccc75106518a75e027c87d37df7c4e0ca55
3
+ metadata.gz: bfb061efc0e39818119aa5e0d6d2fc1b4e30c67f
4
+ data.tar.gz: a7bd9fc29f6f2bfbe5d3f880bdc6fc6b1eb5fbcb
5
5
  SHA512:
6
- metadata.gz: 55efc9670ec8899eb1940fbaa88b92becbed3c4fd1c0377385873892740da213389ceca8d82f60f8b36b83d662ee6518bc66c15a71951cc01596013c4a23e9b2
7
- data.tar.gz: 65dc9db1074a0c2997e7390224abae16c9264c72bf61ff0c3379ce05f2012ee60907708a6f03bb32f09f8bcc6de0efdfb6098a7ff20fca4d37a79dfb51f43542
6
+ metadata.gz: 4675c0ab2bcb626aa2b5203c0ebfaab596d430b882ea086f0fb82c41e5f29e4e4f833b7c34b3e98b60638c85f56e3a4ee135b603e5b50f54e12b083eddb47b4e
7
+ data.tar.gz: 720765653920c29a05ab32a522a2e0796292af9dfe26fcbe55d6d1573054a43d4943d192a93c765668852a7072785f4bbbd2ad8c2bc6fa7a2677793e52a4d9aa
data/README.md CHANGED
@@ -4,37 +4,37 @@
4
4
 
5
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
6
 
7
+ # Requirements
8
+
9
+ This knife plugin currently requires the Knife-Essentials gem to be installed in the same gemset. This requirement is currently hosted here:
10
+
11
+ https://github.com/jkeiser/knife-essentials
12
+
7
13
  # Installation
8
14
 
9
15
  This knife plugin is packaged as a gem. To install it, clone the
10
16
  git repository and run the following:
11
17
 
12
18
  gem build knife-ec-backup.gemspec
13
- gem install knife-ec-backup-0.9.6.gem
19
+ gem install knife-ec-backup-1.0.0.gem
14
20
 
15
21
  # Configuration
16
22
 
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.
23
+ ## Permissions
24
+ Note that most users in an EC installation lack the permissions to pull all of the data from all organizations and other users.
25
+ This plugin **REQUIRES THE PIVOTAL KEY AND WEBUI KEY** from the Chef Server.
26
+ It is recommended that you run this from a frontend Enterprise Chef Server, you can use --user and --key to pass the pivotal information along.
29
27
 
30
28
  # Subcommands
31
29
 
32
- ## knife ec backup DEST_DIR WEBUI_KEY \[USER_ACL_REST\] (options)
30
+ ## knife ec backup DEST_DIR (options)
33
31
 
34
32
  *Options*
35
33
 
36
34
  * `--concurrency`:
37
35
  Maximum number of simultaneous requests to send (default: 10)
36
+ * `--webui-key`:
37
+ Used to set the path to the WebUI Key (default: /etc/opscode/webui_priv.pem)
38
38
  * `--skip-useracl`:
39
39
  Whether to skip downloading User ACLs. This is required for EC 11.0.0 and lower (default: false)
40
40
 
@@ -90,12 +90,14 @@ This compares very closely with the "knife download /" from an OSC server:
90
90
  users
91
91
  <name>.json>
92
92
 
93
- ## knife ec restore DEST_DIR WEBUI_KEY \[USER_ACL_REST\] (options)
93
+ ## knife ec restore DEST_DIR (options)
94
94
 
95
95
  *Options*
96
96
 
97
97
  * `--concurrency`:
98
98
  Maximum number of simultaneous requests to send (default: 10)
99
+ * `--webui-key`:
100
+ Used to set the path to the WebUI Key (default: /etc/opscode/webui_priv.pem)
99
101
  * `--overwrite-pivotal`:
100
102
  Whether to overwrite pivotal's key. Once this is done, future requests will fail until you fix the private key (default: false)
101
103
  * `--skip-useracl`:
@@ -105,4 +107,6 @@ Restores all data from a repository to an Enterprise Chef / Private Chef server.
105
107
 
106
108
  # TODO
107
109
 
108
- * Prevent 403 error for Billing Admins ACL as it is downloaded in another method.
110
+ * Ensure easy installation into embedded ruby gemset on Chef Server.
111
+ * Remove requirement for Knife Essentials gem to be installed.
112
+ * This plugin does **NOT** currently backup user passwords. **They will have to be reset after a restore.**
@@ -9,6 +9,10 @@ class Chef
9
9
  :long => '--concurrency THREADS',
10
10
  :description => 'Maximum number of simultaneous requests to send (default: 10)'
11
11
 
12
+ option :webui_key,
13
+ :long => '--webui-key KEYPATH',
14
+ :description => 'Used to set the path to the WebUI Key (default: /etc/opscode/webui_priv.pem)'
15
+
12
16
  option :skip_useracl,
13
17
  :long => '--skip-useracl',
14
18
  :boolean => true,
@@ -29,22 +33,79 @@ class Chef
29
33
  end
30
34
 
31
35
  def run
32
- if name_args.length == 0
33
- ui.error("Must specify backup directory as argument.")
36
+ #Check for destination directory argument
37
+ if name_args.length <= 0
38
+ ui.error("Must specify backup directory as an argument.")
34
39
  exit 1
35
40
  end
36
-
37
41
  dest_dir = name_args[0]
38
- webui_key = name_args[1]
42
+
43
+
44
+ #Check for pivotal user and key
45
+ node_name = Chef::Config.node_name
46
+ client_key = Chef::Config.client_key
47
+ if node_name != "pivotal"
48
+ if !File.exist?("/etc/opscode/pivotal.pem")
49
+ ui.error("Username not configured as pivotal and /etc/opscode/pivotal.pem does not exist. It is recommended that you run this plugin from your Chef server.")
50
+ exit 1
51
+ end
52
+ Chef::Config.node_name = 'pivotal'
53
+ Chef::Config.client_key = '/etc/opscode/pivotal.pem'
54
+ end
55
+
56
+ #Check for WebUI Key
57
+ if config[:webui_key] == nil
58
+ if !File.exist?("/etc/opscode/webui_priv.pem")
59
+ ui.error("WebUI not specified and /etc/opscode/webui_priv.pem does not exist. It is recommended that you run this plugin from your Chef server.")
60
+ exit 1
61
+ end
62
+ ui.warn("WebUI not specified. Using /etc/opscode/webui_priv.pem")
63
+ webui_key = '/etc/opscode/webui_priv.pem'
64
+ else
65
+ webui_key = config[:webui_key]
66
+ end
67
+
68
+ #Set the server root
69
+ server_root = Chef::Config.chef_server_root
70
+ if server_root == nil
71
+ server_root = Chef::Config.chef_server_url.gsub(/\/organizations\/+[^\/]+\/*$/, '')
72
+ ui.warn("chef_server_root not found in knife configuration. Setting root to: #{server_root}")
73
+ Chef::Config.chef_server_root = server_root
74
+ end
75
+
39
76
  rest = Chef::REST.new(Chef::Config.chef_server_root)
40
- if name_args.length >= 3
41
- user_acl_rest = Chef::REST.new(name_args[2])
77
+ user_acl_rest = Chef::REST.new("http://127.0.0.1:9465")
78
+
79
+ # Grab Chef Server version number so that we can auto set options
80
+ uri = URI.parse("#{Chef::Config.chef_server_root}/version")
81
+ version_manifest = open(uri, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
82
+ server_version = version_manifest.grep(/private-chef /).first.split(' ').last
83
+
84
+ server_version_parts = server_version.split('.')
85
+
86
+ if server_version_parts.count == 3
87
+ puts "Detected Enterprise Chef Server version: #{server_version}"
88
+
89
+ # All versions of Chef Server below 11.0.1 are missing the GET User ACL helper in nginx
90
+ if server_version_parts[0] < 11 || (server_version_parts[0] == 11 && server_version_parts[1] == 0 && server_version_parts[0] < 1)
91
+ #Check to see if Opscode-Account can be directly from the local machine
92
+ begin
93
+ user_acl_rest.get('users')
94
+ ui.warn("Your version of Enterprise Chef Server does not support the downloading of User ACLs. Using local connection to backup")
95
+ rescue
96
+ ui.warn("Your version of Enterprise Chef Server does not support the downloading of User ACLs. Setting skip-useracl to TRUE")
97
+ config[:skip_useracl] = true
98
+ user_acl_rest = nil
99
+ end
100
+ end
101
+
42
102
  else
43
- user_acl_rest = rest
103
+ ui.warn("Unable to detect Chef Server version.")
44
104
  end
45
105
 
46
106
  # Grab users
47
107
  puts "Grabbing users ..."
108
+
48
109
  ensure_dir("#{dest_dir}/users")
49
110
  ensure_dir("#{dest_dir}/user_acls")
50
111
 
@@ -54,7 +115,7 @@ class Chef
54
115
  end
55
116
 
56
117
  if config[:skip_useracl]
57
- ui.warn("Skipping user ACL download for #{name}. To download this ACL, remove --skip-useracl.")
118
+ ui.warn("Skipping user ACL download for #{name}. To download this ACL, remove --skip-useracl or upgrade your Enterprise Chef Server.")
58
119
  next
59
120
  end
60
121
 
@@ -129,12 +190,15 @@ class Chef
129
190
  Chef::Config.client_key = webui_key
130
191
  Chef::Config.custom_http_headers = (Chef::Config.custom_http_headers || {}).merge({'x-ops-request-source' => 'web'})
131
192
 
132
- # Do the download
193
+ # Download the entire org skipping the billing admins group ACL
133
194
  chef_fs_config = ::ChefFS::Config.new
134
- root_pattern = ::ChefFS::FilePattern.new('/')
135
- if ::ChefFS::FileSystem.copy_to(root_pattern, chef_fs_config.chef_fs, chef_fs_config.local_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
136
- @error = true
195
+ top_level_paths = chef_fs_config.chef_fs.children.select { |entry| entry.name != 'acls' }.map { |entry| entry.path }
196
+ acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.chef_fs, ::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
197
+ 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 }
198
+ (top_level_paths + group_acl_paths + acl_paths).each do |path|
199
+ ::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) })
137
200
  end
201
+
138
202
  ensure
139
203
  CONFIG_VARS.each do |key|
140
204
  Chef::Config[key.to_sym] = old_config[key]
@@ -9,6 +9,10 @@ class Chef
9
9
  :long => '--concurrency THREADS',
10
10
  :description => 'Maximum number of simultaneous requests to send (default: 10)'
11
11
 
12
+ option :webui_key,
13
+ :long => '--webui-key KEYPATH',
14
+ :description => 'Used to set the path to the WebUI Key (default: /etc/opscode/webui_priv.pem)'
15
+
12
16
  option :overwrite_pivotal,
13
17
  :long => '--overwrite-pivotal',
14
18
  :boolean => true,
@@ -40,22 +44,69 @@ class Chef
40
44
  end
41
45
 
42
46
  def run
43
- if name_args.length == 0
44
- ui.error("Must specify backup directory as argument.")
47
+ #Check for destination directory argument
48
+ if name_args.length <= 0
49
+ ui.error("Must specify backup directory as an argument.")
45
50
  exit 1
46
51
  end
47
-
48
52
  dest_dir = name_args[0]
49
- webui_key = name_args[1]
50
- rest = Chef::REST.new(Chef::Config.chef_server_root)
51
- if name_args.length >= 3
52
- user_acl_rest = Chef::REST.new(name_args[2])
53
+
54
+ #Check for pivotal user and key
55
+ node_name = Chef::Config.node_name
56
+ client_key = Chef::Config.client_key
57
+ if node_name != "pivotal"
58
+ if !File.exist?("/etc/opscode/pivotal.pem")
59
+ ui.error("Username not configured as pivotal and /etc/opscode/pivotal.pem does not exist. It is recommended that you run this plugin from your Chef server.")
60
+ exit 1
61
+ end
62
+ the_node_name = 'pivotal'
63
+ the_client_key = '/etc/opscode/pivotal.pem'
64
+ end
65
+
66
+ #Check for WebUI Key
67
+ if config[:webui_key] == nil
68
+ if !File.exist?("/etc/opscode/webui_priv.pem")
69
+ ui.error("WebUI not specified and /etc/opscode/webui_priv.pem does not exist. It is recommended that you run this plugin from your Chef server.")
70
+ exit 1
71
+ end
72
+ ui.warn("WebUI not specified. Using /etc/opscode/webui_priv.pem")
73
+ webui_key = '/etc/opscode/webui_priv.pem'
74
+ else
75
+ webui_key = config[:webui_key]
76
+ end
77
+
78
+ #Set the server root
79
+ server_root = Chef::Config.chef_server_root
80
+ if server_root == nil
81
+ server_root = Chef::Config.chef_server_url.gsub(/\/organizations\/+[^\/]+\/*$/, '')
82
+ ui.warn("chef_server_root not found in knife configuration. Setting root to: #{server_root}")
83
+ Chef::Config.chef_server_root = server_root
84
+ end
85
+
86
+ # Grab Chef Server version number so that we can auto set options
87
+ uri = URI.parse("#{Chef::Config.chef_server_root}/version")
88
+ version_manifest = open(uri, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
89
+ server_version = version_manifest.grep(/private-chef /).first.split(' ').last
90
+
91
+ server_version_parts = server_version.split('.')
92
+
93
+ if server_version_parts.count == 3
94
+ puts "Detected Enterprise Chef Server version: #{server_version}"
95
+
96
+ # All versions of Chef Server below 11.0.X are unable to update user acls
97
+ if server_version_parts[0] < 11 || (server_version_parts[0] == 11 && server_version_parts[1] == 0)
98
+ ui.warn("Your version of Enterprise Chef Server does not support the updating of User ACLs. Setting skip-useracl to TRUE")
99
+ config[:skip_useracl] = true
100
+ end
53
101
  else
54
- user_acl_rest = rest
102
+ ui.warn("Unable to detect Chef Server version.")
55
103
  end
56
104
 
57
105
  # Restore users
58
106
  puts "Restoring users ..."
107
+
108
+ rest = Chef::REST.new(Chef::Config.chef_server_root)
109
+
59
110
  Dir.foreach("#{dest_dir}/users") do |filename|
60
111
  next if filename !~ /(.+)\.json/
61
112
  name = $1
@@ -135,7 +186,7 @@ class Chef
135
186
  next if filename !~ /(.+)\.json/
136
187
  name = $1
137
188
  if config[:skip_useracl]
138
- ui.warn("Skipping user ACL update for #{name}. To update this ACL, remove --skip-useracl.")
189
+ ui.warn("Skipping user ACL update for #{name}. To update this ACL, remove --skip-useracl or upgrade your Enterprise Chef Server.")
139
190
  next
140
191
  end
141
192
  if name == 'pivotal' && !config[:overwrite_pivotal]
@@ -145,7 +196,7 @@ class Chef
145
196
 
146
197
  # Update user acl
147
198
  user_acl = JSONCompat.from_json(IO.read("#{dest_dir}/user_acls/#{name}.json"))
148
- put_acl(user_acl_rest, "users/#{name}/_acl", user_acl)
199
+ put_acl(rest, "users/#{name}/_acl", user_acl)
149
200
  end
150
201
 
151
202
 
@@ -1,3 +1,3 @@
1
1
  module KnifeECBackup
2
- VERSION = '1.0'
2
+ VERSION = '1.1.0'
3
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: '1.0'
4
+ version: 1.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-12-10 00:00:00.000000000 Z
11
+ date: 2013-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -72,9 +72,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
72
  version: '0'
73
73
  requirements: []
74
74
  rubyforge_project:
75
- rubygems_version: 2.0.3
75
+ rubygems_version: 2.1.5
76
76
  signing_key:
77
77
  specification_version: 4
78
78
  summary: Backup and Restore of Enterprise Chef
79
79
  test_files: []
80
- has_rdoc: