knife-ec-backup 1.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: