knife-ec-backup 1.1.8 → 1.1.9

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: 555db6e18f609eb180e4903ce2ca211db5f33444
4
- data.tar.gz: 07a794b5dbd08e1c383eb25072ff88e20cdfbcb5
3
+ metadata.gz: 2f6ccb75df554513932811d591b998bc003b5e2a
4
+ data.tar.gz: f483c5827dc422e42a77a1f3c0d38c6afd23ca44
5
5
  SHA512:
6
- metadata.gz: d4679a94465e27cfdbb81930aa828fef32523df2dced01c7be95141691dfe91693ae8749e8003666879f8c04fa331bed31ca9a1a805a400006b9757f0d52ee37
7
- data.tar.gz: 23e4d67586e1ff4b6c9e934ff770fdfe6c5bc14c5dcee06e6ba39ab67540f70d7bb7eec6e90f93b01ca2ddc7898c25bad3bef6c2cec1a984004cd8442132d48a
6
+ metadata.gz: 5faefbd227c50d317b3570ccb88f2c9a0a5e44e7dd5cdca7482b667eafdaf0b779e51c491a83127939da69082c11916df1acf4e48663e80300ce2ede6307dbc8
7
+ data.tar.gz: a3a8ddadea8cfd3ff190aca59120edf249e59194355e9a97f7fc438c0e692b7bed5cc270ac70735bb246124a0a8679ebde34065f3a4c507ef8af57f6d6c9252f
@@ -3,7 +3,7 @@ require 'chef/knife'
3
3
  class Chef
4
4
  class Knife
5
5
  class EcBackup < Chef::Knife
6
- banner "knife ec backup"
6
+ banner "knife ec backup DIRECTORY"
7
7
 
8
8
  option :concurrency,
9
9
  :long => '--concurrency THREADS',
@@ -25,6 +25,10 @@ class Chef
25
25
  :default => false,
26
26
  :description => "Whether to skip checking the Chef Server version. This will also skip any auto-configured options"
27
27
 
28
+ option :org,
29
+ :long => '--only-org ORGNAME',
30
+ :description => "Only back up objects in the named organization (default: all orgs)"
31
+
28
32
  deps do
29
33
  require 'chef_fs/config'
30
34
  require 'chef_fs/file_system'
@@ -140,8 +144,9 @@ class Chef
140
144
  # Download organizations
141
145
  ensure_dir("#{dest_dir}/organizations")
142
146
  rest.get_rest('/organizations').each_pair do |name, url|
147
+ do_org = (config[:org].nil? || config[:org] == name)
143
148
  org = rest.get_rest(url)
144
- if org['assigned_at']
149
+ if org['assigned_at'] and do_org
145
150
  puts "Grabbing organization #{name} ..."
146
151
  ensure_dir("#{dest_dir}/organizations/#{name}")
147
152
  download_org(dest_dir, webui_key, name)
@@ -0,0 +1,74 @@
1
+ #
2
+ # Author:: Steven Danna (<steve@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+
21
+ class Chef
22
+ class Knife
23
+ module EcKeyBase
24
+
25
+ def self.included(includer)
26
+ includer.class_eval do
27
+
28
+ deps do
29
+ require 'sequel'
30
+ require 'json'
31
+ end
32
+
33
+ option :sql_host,
34
+ :long => '--sql-host HOSTNAME',
35
+ :description => 'Postgresql database hostname (default: localhost)',
36
+ :default => "localhost"
37
+
38
+ option :sql_port,
39
+ :long => '--sql-port PORT',
40
+ :description => 'Postgresql database port (default: 5432)',
41
+ :default => 5432
42
+
43
+ option :sql_user,
44
+ :long => "--sql-user USERNAME",
45
+ :description => 'User used to connect to the postgresql database.'
46
+
47
+ option :sql_password,
48
+ :long => "--sql-password PASSWORD",
49
+ :description => 'Password used to connect to the postgresql database'
50
+ end
51
+ end
52
+
53
+ def db
54
+ @db ||= begin
55
+ server_string = "#{config[:sql_user]}:#{config[:sql_password]}@#{config[:sql_host]}:#{config[:sql_port]}/opscode_chef"
56
+ Sequel.connect("postgres://#{server_string}")
57
+ end
58
+ end
59
+
60
+ # Loads SQL user and password from running config if not passed
61
+ # as a command line option
62
+ def load_config_from_file!
63
+ if ! File.exists?("/etc/opscode/chef-server-running.json")
64
+ ui.fatal "SQL User or Password not provided as option and running config cannot be found!"
65
+ exit 1
66
+ else
67
+ running_config ||= JSON.parse(File.read("/etc/opscode/chef-server-running.json"))
68
+ config[:sql_user] ||= running_config['private_chef']['postgresql']['sql_user']
69
+ config[:sql_password] ||= running_config['private_chef']['postgresql']['sql_password']
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Author:: Steven Danna (<steve@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+ require 'chef/knife/ec_key_base'
21
+
22
+ class Chef
23
+ class Knife
24
+ class EcKeyExport < Chef::Knife
25
+
26
+ include Knife::EcKeyBase
27
+
28
+ banner "knife ec key export [PATH]"
29
+
30
+ def run
31
+ if config[:sql_user].nil? || config[:sql_password].nil?
32
+ load_config_from_file!
33
+ end
34
+
35
+ path = @name_args[0] || "key_dump.json"
36
+ export(path)
37
+ end
38
+
39
+ def export(path)
40
+ users = db.select(:username, :public_key, :pubkey_version, :hashed_password, :salt, :hash_type).from(:users)
41
+ File.open(path, 'w') { |file| file.write(users.all.to_json) }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,76 @@
1
+ #
2
+ # Author:: Steven Danna (<steve@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+ require 'chef/knife/ec_key_base'
21
+
22
+ class Chef
23
+ class Knife
24
+ class EcKeyImport < Chef::Knife
25
+
26
+ include Knife::EcKeyBase
27
+
28
+ banner "knife ec key import [PATH]"
29
+
30
+ option :skip_pivotal,
31
+ :long => "--[no-]skip-pivotal",
32
+ :default => true,
33
+ :boolean => true,
34
+ :description => "Upload pivotal key. By default the pivotal key is not uploaded."
35
+
36
+ def run
37
+ if config[:sql_user].nil? || config[:sql_password].nil?
38
+ load_config_from_file!
39
+ end
40
+
41
+ path = @name_args[0] || "key_dump.json"
42
+ import(path)
43
+ end
44
+
45
+
46
+ def import(path)
47
+ key_data = JSON.parse(File.read(path))
48
+ key_data.each do |d|
49
+ username = d['username']
50
+ key = d['public_key']
51
+ version = d['pubkey_version']
52
+ hashed_password = d['hashed_password']
53
+ hash_type = d['hash_type']
54
+ salt = d['salt']
55
+
56
+ if username == 'pivotal' && config[:skip_pivotal]
57
+ ui.warn "Skipping pivotal user."
58
+ next
59
+ end
60
+
61
+ ui.msg "Updating key for #{username}"
62
+ users_to_update = db[:users].where(:username => username)
63
+ if users_to_update.count != 1
64
+ ui.warn "Wrong number of users to update for #{username}. Skipping"
65
+ else
66
+ users_to_update.update(:public_key => key,
67
+ :pubkey_version => version,
68
+ :salt => salt,
69
+ :hashed_password => hashed_password,
70
+ :hash_type => hash_type)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -3,7 +3,7 @@ require 'chef/knife'
3
3
  class Chef
4
4
  class Knife
5
5
  class EcRestore < Chef::Knife
6
- banner "knife ec restore"
6
+ banner "knife ec restore DIRECTORY"
7
7
 
8
8
  option :concurrency,
9
9
  :long => '--concurrency THREADS',
@@ -40,6 +40,7 @@ class Chef
40
40
  require 'chef_fs/data_handler/acl_data_handler'
41
41
  require 'securerandom'
42
42
  require 'chef_fs/parallelizer'
43
+ require 'chef/tsorter'
43
44
  end
44
45
 
45
46
  def configure_chef
@@ -64,8 +65,8 @@ class Chef
64
65
  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.")
65
66
  exit 1
66
67
  end
67
- node_name = 'pivotal'
68
- client_key = '/etc/opscode/pivotal.pem'
68
+ Chef::Config.node_name = 'pivotal'
69
+ Chef::Config.client_key = '/etc/opscode/pivotal.pem'
69
70
  end
70
71
 
71
72
  #Check for WebUI Key
@@ -268,9 +269,14 @@ class Chef
268
269
  puts "Restoring the rest of the org"
269
270
  chef_fs_config = ::ChefFS::Config.new
270
271
  top_level_paths = chef_fs_config.local_fs.children.select { |entry| entry.name != 'acls' && entry.name != 'groups' }.map { |entry| entry.path }
271
- acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
272
+
273
+ # Topologically sort groups for upload
274
+ unsorted_groups = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| JSON.parse(entry.read) }
275
+ group_paths = sort_groups_for_upload(unsorted_groups).map { |group_name| "/groups/#{group_name}.json" }
276
+
272
277
  group_acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/acls/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
273
- group_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/groups/*')).select { |entry| entry.name != 'billing-admins.json' }.map { |entry| entry.path }
278
+ acl_paths = ::ChefFS::FileSystem.list(chef_fs_config.local_fs, ::ChefFS::FilePattern.new('/acls/*')).select { |entry| entry.name != 'groups' }.map { |entry| entry.path }
279
+
274
280
  (top_level_paths + group_paths + group_acl_paths + acl_paths).each do |path|
275
281
  ::ChefFS::FileSystem.copy_to(::ChefFS::FilePattern.new(path), chef_fs_config.local_fs, chef_fs_config.chef_fs, nil, config, ui, proc { |entry| chef_fs_config.format_path(entry) })
276
282
  end
@@ -279,7 +285,7 @@ class Chef
279
285
  Chef::Config[:client_key] = old_config['client_key']
280
286
  Chef::Config.custom_http_headers = {}
281
287
  ['admins', 'billing-admins'].each do |group|
282
- restore_group(::ChefFS::Config.new, group, :users => false)
288
+ restore_group(::ChefFS::Config.new, group)
283
289
  end
284
290
  ensure
285
291
  CONFIG_VARS.each do |key|
@@ -288,6 +294,25 @@ class Chef
288
294
  end
289
295
  end
290
296
 
297
+ # Takes an array of group objects
298
+ # and topologically sorts them
299
+ def sort_groups_for_upload(groups)
300
+ Chef::Tsorter.new(group_array_to_sortable_hash(groups)).tsort
301
+ end
302
+
303
+ def group_array_to_sortable_hash(groups)
304
+ ret = {}
305
+ groups.each do |group|
306
+ name = group["name"]
307
+ ret[name] = if group.key?("groups")
308
+ group["groups"]
309
+ else
310
+ []
311
+ end
312
+ end
313
+ ret
314
+ end
315
+
291
316
  def restore_group(chef_fs_config, group_name, includes = {:users => true, :clients => true})
292
317
  includes[:users] = true unless includes.key? :users
293
318
  includes[:clients] = true unless includes.key? :clients
@@ -0,0 +1,20 @@
1
+ require 'tsort'
2
+
3
+ class Chef
4
+ class Tsorter
5
+
6
+ include TSort
7
+
8
+ def initialize(data)
9
+ @data = data
10
+ end
11
+
12
+ def tsort_each_node(&block)
13
+ @data.each_key(&block)
14
+ end
15
+
16
+ def tsort_each_child(node, &block)
17
+ @data.fetch(node).each(&block)
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module KnifeECBackup
2
- VERSION = '1.1.8'
2
+ VERSION = '1.1.9'
3
3
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-ec-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
4
+ version: 1.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-31 00:00:00.000000000 Z
11
+ date: 2014-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: knife-essentials
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sequel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pg
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  - !ruby/object:Gem::Dependency
14
56
  name: rspec
15
57
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +92,11 @@ files:
50
92
  - README.md
51
93
  - Rakefile
52
94
  - lib/chef/knife/ec_backup.rb
95
+ - lib/chef/knife/ec_key_base.rb
96
+ - lib/chef/knife/ec_key_export.rb
97
+ - lib/chef/knife/ec_key_import.rb
53
98
  - lib/chef/knife/ec_restore.rb
99
+ - lib/chef/tsorter.rb
54
100
  - lib/knife_ec_backup/version.rb
55
101
  homepage: http://www.opscode.com
56
102
  licenses:
@@ -72,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
118
  version: '0'
73
119
  requirements: []
74
120
  rubyforge_project:
75
- rubygems_version: 2.1.5
121
+ rubygems_version: 2.0.14
76
122
  signing_key:
77
123
  specification_version: 4
78
124
  summary: Backup and Restore of Enterprise Chef