knife-essentials 1.3 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,11 +22,6 @@ EOM
22
22
  require 'chef_fs/chef_fs_data_store'
23
23
  end
24
24
 
25
- option :remote,
26
- :long => '--remote',
27
- :boolean => true,
28
- :description => "Proxy the remote server instead of the local filesystem"
29
-
30
25
  option :host,
31
26
  :short => '-H',
32
27
  :long => '--host=HOST',
@@ -44,7 +39,7 @@ EOM
44
39
 
45
40
  def run
46
41
  server_options = {}
47
- server_options[:data_store] = ChefFS::ChefFSDataStore.new(proc { config[:remote] ? create_chef_fs : create_local_fs })
42
+ server_options[:data_store] = ChefFS::ChefFSDataStore.new(local_fs)
48
43
  server_options[:log_level] = Chef::Log.level
49
44
  server_options[:host] = config[:host] if config[:host]
50
45
  server_options[:port] = config[:port] ? config[:port].to_i : 4000
@@ -35,11 +35,7 @@ module ChefFS
35
35
  "Reading and writing data to #{chef_fs.fs_description}"
36
36
  end
37
37
 
38
- def chef_fs
39
- @chef_fs.call
40
- end
41
-
42
- MEMORY_PATHS = %w(sandboxes file_store)
38
+ attr_reader :chef_fs
43
39
 
44
40
  def create_dir(path, name, *options)
45
41
  if use_memory_store?(path)
@@ -5,7 +5,7 @@ module ChefFS
5
5
  class AclDataHandler < DataHandlerBase
6
6
  def normalize(node, entry)
7
7
  # Normalize the order of the keys for easier reading
8
- result = super(node, {
8
+ result = normalize_hash(node, {
9
9
  'create' => {},
10
10
  'read' => {},
11
11
  'update' => {},
@@ -13,7 +13,7 @@ module ChefFS
13
13
  'grant' => {}
14
14
  })
15
15
  result.keys.each do |key|
16
- result[key] = super(result[key], { 'actors' => [], 'groups' => [] })
16
+ result[key] = normalize_hash(result[key], { 'actors' => [], 'groups' => [] })
17
17
  result[key]['actors'] = result[key]['actors'].sort
18
18
  result[key]['groups'] = result[key]['groups'].sort
19
19
  end
@@ -16,7 +16,7 @@ module ChefFS
16
16
  if entry.org
17
17
  defaults['orgname'] = entry.org
18
18
  end
19
- result = super(client, defaults)
19
+ result = normalize_hash(client, defaults)
20
20
  # You can NOT send json_class, or it will fail
21
21
  result.delete('json_class')
22
22
  result
@@ -4,7 +4,7 @@ module ChefFS
4
4
  module DataHandler
5
5
  class ContainerDataHandler < DataHandlerBase
6
6
  def normalize(container, entry)
7
- super(container, {
7
+ normalize_hash(container, {
8
8
  'containername' => remove_dot_json(entry.name),
9
9
  'containerpath' => remove_dot_json(entry.name)
10
10
  })
@@ -7,7 +7,7 @@ module ChefFS
7
7
  def normalize(cookbook, entry)
8
8
  version = entry.name
9
9
  name = entry.parent.name
10
- result = super(cookbook, {
10
+ result = normalize_hash(cookbook, {
11
11
  'name' => "#{name}-#{version}",
12
12
  'version' => version,
13
13
  'cookbook_name' => name,
@@ -16,7 +16,7 @@ module ChefFS
16
16
  'frozen?' => false,
17
17
  'metadata' => {}
18
18
  })
19
- result['metadata'] = super(result['metadata'], {
19
+ result['metadata'] = normalize_hash(result['metadata'], {
20
20
  'version' => version,
21
21
  'name' => name
22
22
  })
@@ -9,16 +9,17 @@ module ChefFS
9
9
  if data_bag_item['json_class'] == 'Chef::DataBagItem' && data_bag_item['raw_data']
10
10
  data_bag_item = data_bag_item['raw_data']
11
11
  end
12
- # chef_type and data_bag only come back from PUT and POST, but we'll
13
- # normalize them in in case someone is comparing with those results.
14
- super(data_bag_item, {
15
- 'chef_type' => 'data_bag_item',
16
- 'data_bag' => entry.parent.name,
12
+ # chef_type and data_bag come back in PUT and POST results, but we don't
13
+ # use those in knife-essentials.
14
+ normalize_hash(data_bag_item, {
17
15
  'id' => remove_dot_json(entry.name)
18
16
  })
19
17
  end
20
18
 
21
19
  def normalize_for_post(data_bag_item, entry)
20
+ if data_bag_item['json_class'] == 'Chef::DataBagItem' && data_bag_item['raw_data']
21
+ data_bag_item = data_bag_item['raw_data']
22
+ end
22
23
  {
23
24
  "name" => "data_bag_item_#{entry.parent.name}_#{remove_dot_json(entry.name)}",
24
25
  "json_class" => "Chef::DataBagItem",
@@ -26,7 +26,7 @@ module ChefFS
26
26
  normalize({}, entry)
27
27
  end
28
28
 
29
- def normalize(object, defaults)
29
+ def normalize_hash(object, defaults)
30
30
  # Make a normalized result in the specified order for diffing
31
31
  result = {}
32
32
  defaults.each_pair do |key, default|
@@ -5,7 +5,7 @@ module ChefFS
5
5
  module DataHandler
6
6
  class EnvironmentDataHandler < DataHandlerBase
7
7
  def normalize(environment, entry)
8
- super(environment, {
8
+ normalize_hash(environment, {
9
9
  'name' => remove_dot_json(entry.name),
10
10
  'description' => '',
11
11
  'cookbook_versions' => {},
@@ -15,7 +15,7 @@ module ChefFS
15
15
  if entry.org
16
16
  defaults['orgname'] = entry.org
17
17
  end
18
- result = super(group, defaults)
18
+ result = normalize_hash(group, defaults)
19
19
  if result['actors'] && result['actors'].sort.uniq == (result['users'] + result['clients']).sort.uniq
20
20
  result.delete('actors')
21
21
  end
@@ -5,7 +5,7 @@ module ChefFS
5
5
  module DataHandler
6
6
  class NodeDataHandler < DataHandlerBase
7
7
  def normalize(node, entry)
8
- result = super(node, {
8
+ result = normalize_hash(node, {
9
9
  'name' => remove_dot_json(entry.name),
10
10
  'json_class' => 'Chef::Node',
11
11
  'chef_type' => 'node',
@@ -5,7 +5,7 @@ module ChefFS
5
5
  module DataHandler
6
6
  class RoleDataHandler < DataHandlerBase
7
7
  def normalize(role, entry)
8
- result = super(role, {
8
+ result = normalize_hash(role, {
9
9
  'name' => remove_dot_json(entry.name),
10
10
  'description' => '',
11
11
  'json_class' => 'Chef::Role',
@@ -4,7 +4,7 @@ module ChefFS
4
4
  module DataHandler
5
5
  class UserDataHandler < DataHandlerBase
6
6
  def normalize(user, entry)
7
- super(user, {
7
+ normalize_hash(user, {
8
8
  'name' => remove_dot_json(entry.name),
9
9
  'admin' => false,
10
10
  'json_class' => 'Chef::WebUIUser',
@@ -81,11 +81,10 @@ module ChefFS
81
81
  end
82
82
 
83
83
  def children
84
- @children ||=
85
- Dir.entries(file_path).sort.
86
- select { |entry| entry != '.' && entry != '..' }.
87
- map { |entry| ChefRepositoryFileSystemEntry.new(entry, self) }.
88
- select { |entry| !ignored?(entry) }
84
+ Dir.entries(file_path).sort.
85
+ select { |entry| entry != '.' && entry != '..' }.
86
+ map { |entry| ChefRepositoryFileSystemEntry.new(entry, self) }.
87
+ select { |entry| !ignored?(entry) }
89
88
  end
90
89
 
91
90
  private
@@ -39,7 +39,7 @@ module ChefFS
39
39
 
40
40
  def children
41
41
  begin
42
- @children ||= Dir.entries(file_path).sort.select { |entry| entry != '.' && entry != '..' }.map { |entry| FileSystemEntry.new(entry, self) }
42
+ Dir.entries(file_path).sort.select { |entry| entry != '.' && entry != '..' }.map { |entry| FileSystemEntry.new(entry, self) }
43
43
  rescue Errno::ENOENT
44
44
  raise ChefFS::FileSystem::NotFoundError.new(self, $!)
45
45
  end
@@ -1,3 +1,3 @@
1
1
  module ChefFS
2
- VERSION = "1.3"
2
+ VERSION = "1.3.2"
3
3
  end
@@ -0,0 +1 @@
1
+ $__KNIFE_INTEGRATION_FAILSAFE_CHECK << " ole"
@@ -1,4 +1,4 @@
1
- require 'thin'
1
+ require 'puma'
2
2
  require 'support/integration_helper'
3
3
  require 'chef/knife/list_essentials'
4
4
 
@@ -16,18 +16,11 @@ describe 'redirection' do
16
16
  app = lambda do |env|
17
17
  [302, {'Content-Type' => 'text','Location' => "#{@real_chef_server_url}#{env['PATH_INFO']}" }, ['302 found'] ]
18
18
  end
19
- Thin::Logging.silent = true
20
- @redirector_server = Thin::Server.new('127.0.0.1', 9018, app, { :signals => false })
21
- @redirector_thread = Thread.new do
22
- begin
23
- @redirector_server.start
24
- rescue
25
- @server_error = $!
26
- Chef::Log.error("#{$!.message}\n#{$!.backtrace.join("\n")}")
27
- end
28
- end
19
+ @redirector_server = Puma::Server.new(app, Puma::Events.new(STDERR, STDOUT))
20
+ @redirector_server.add_tcp_listener("127.0.0.1", 9018)
21
+ @redirector_server.run
29
22
  Timeout::timeout(5) do
30
- until @redirector_server.running? || @server_error
23
+ until @redirector_server.running
31
24
  sleep(0.01)
32
25
  end
33
26
  raise @server_error if @server_error
@@ -36,10 +29,7 @@ describe 'redirection' do
36
29
 
37
30
  after :each do
38
31
  Chef::Config.chef_server_url = @real_chef_server_url
39
- @redirector_thread.kill
40
- @redirector_thread.join(nil)
41
- @redirector_thread = nil
42
- @redirector_server = nil
32
+ @redirector_server.stop(true)
43
33
  end
44
34
 
45
35
  it 'knife list /roles returns the role' do
@@ -1,6 +1,7 @@
1
1
  require 'support/integration_helper'
2
2
  require 'chef/knife/upload_essentials'
3
3
  require 'chef/knife/diff_essentials'
4
+ require 'chef/knife/raw_essentials'
4
5
 
5
6
  describe 'knife upload' do
6
7
  extend IntegrationSupport
@@ -209,8 +210,36 @@ EOM
209
210
  end
210
211
  end
211
212
 
212
- # Test upload of an item when the other end doesn't even have the container
213
213
  when_the_chef_server 'is empty' do
214
+ when_the_repository 'has a data bag item' do
215
+ file 'data_bags/x/y.json', { 'foo' => 'bar' }
216
+ it 'knife upload of the data bag uploads only the values in the data bag item and no other' do
217
+ knife('upload /data_bags/x/y.json').should_succeed <<EOM
218
+ Created /data_bags/x
219
+ Created /data_bags/x/y.json
220
+ EOM
221
+ knife('diff --name-status /data_bags').should_succeed <<EOM
222
+ EOM
223
+ JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
224
+ end
225
+ end
226
+
227
+ when_the_repository 'has a data bag item with keys chef_type and data_bag' do
228
+ file 'data_bags/x/y.json', { 'chef_type' => 'aaa', 'data_bag' => 'bbb' }
229
+ it 'upload preserves chef_type and data_bag' do
230
+ knife('upload /data_bags/x/y.json').should_succeed <<EOM
231
+ Created /data_bags/x
232
+ Created /data_bags/x/y.json
233
+ EOM
234
+ knife('diff --name-status /data_bags').should_succeed ''
235
+ result = JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false)
236
+ result.keys.sort.should == [ 'chef_type', 'data_bag', 'id' ]
237
+ result['chef_type'].should == 'aaa'
238
+ result['data_bag'].should == 'bbb'
239
+ end
240
+ end
241
+
242
+ # Test upload of an item when the other end doesn't even have the container
214
243
  when_the_repository 'has two data bag items' do
215
244
  file 'data_bags/x/y.json', {}
216
245
  file 'data_bags/x/z.json', {}
@@ -566,10 +595,10 @@ D\t/roles/x.json
566
595
  D\t/users/admin.json
567
596
  D\t/users/x.json
568
597
  EOM
569
- end
598
+ end
570
599
 
571
- it 'knife upload --purge deletes everything' do
572
- knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
600
+ it 'knife upload --purge deletes everything' do
601
+ knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
573
602
  Deleted extra entry /clients/chef-validator.json (purge is on)
574
603
  Deleted extra entry /clients/chef-webui.json (purge is on)
575
604
  Deleted extra entry /clients/x.json (purge is on)
@@ -581,10 +610,10 @@ Deleted extra entry /roles/x.json (purge is on)
581
610
  Deleted extra entry /users/admin.json (purge is on)
582
611
  Deleted extra entry /users/x.json (purge is on)
583
612
  EOM
584
- knife('diff --name-status /').should_succeed <<EOM
613
+ knife('diff --name-status /').should_succeed <<EOM
585
614
  D\t/environments/_default.json
586
615
  EOM
587
- end
616
+ end
588
617
  end
589
618
 
590
619
  when_the_repository 'has an identical copy of each thing' do
@@ -30,14 +30,14 @@ module IntegrationSupport
30
30
 
31
31
  def self.extended(base)
32
32
  base.before :each do
33
- @old_repo_mode = nil
34
- @old_versioned_cookbooks = nil
33
+ # We mess with Chef::Config a lot. Save and restore it.
34
+ @old_chef_config = Chef::Config.configuration
35
+ Chef::Config.configuration = Chef::Config.configuration.dup
35
36
  Chef::Config.repo_mode = nil
36
37
  Chef::Config.versioned_cookbooks = nil
37
38
  end
38
39
  base.after :each do
39
- Chef::Config.repo_mode = @old_repo_mode
40
- Chef::Config.versioned_cookbooks = @old_versioned_cookbooks
40
+ Chef::Config.configuration = @old_chef_config
41
41
  end
42
42
  end
43
43
 
@@ -45,7 +45,20 @@ module KnifeSupport
45
45
 
46
46
  # Don't print stuff
47
47
  Chef::Config[:verbosity] = ( DEBUG ? 2 : 0 )
48
+ instance.config[:config_file] = File.join(CHEF_SPEC_DATA, "null_config.rb")
49
+
50
+ # Configure chef with a (mostly) blank knife.rb
51
+ # We set a global and then mutate it in our stub knife.rb so we can be
52
+ # extra sure that we're not loading someone's real knife.rb and then
53
+ # running test scenarios against a real chef server. If things don't
54
+ # smell right, abort.
55
+
56
+ $__KNIFE_INTEGRATION_FAILSAFE_CHECK = "ole"
48
57
  instance.configure_chef
58
+
59
+ unless $__KNIFE_INTEGRATION_FAILSAFE_CHECK == "ole ole"
60
+ raise Exception, "Potential misconfiguration of integration tests detected. Aborting test."
61
+ end
49
62
  logger = Logger.new(stderr)
50
63
  logger.formatter = proc { |severity, datetime, progname, msg| "#{severity}: #{msg}\n" }
51
64
  Chef::Log.use_log_devices([logger])
@@ -1,5 +1,7 @@
1
1
  require 'support/file_system_support'
2
2
 
3
+ CHEF_SPEC_DATA = File.join(File.dirname(File.dirname(__FILE__)), 'data')
4
+
3
5
  RSpec.configure do |config|
4
6
  config.filter_run :focus => true
5
7
  config.run_all_when_everything_filtered = true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-essentials
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.3'
4
+ version: 1.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-07 00:00:00.000000000 Z
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -92,21 +92,21 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: thin
95
+ name: puma
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>='
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: '1.6'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ! '>='
107
+ - - ~>
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: '1.6'
110
110
  description: Universal knife verbs that work with your Chef repository
111
111
  email: jkeiser@opscode.com
112
112
  executables: []
@@ -190,6 +190,7 @@ files:
190
190
  - spec/chef_fs/diff_spec.rb
191
191
  - spec/chef_fs/file_pattern_spec.rb
192
192
  - spec/chef_fs/file_system_spec.rb
193
+ - spec/data/null_config.rb
193
194
  - spec/integration/chef_repo_path_spec.rb
194
195
  - spec/integration/chef_repository_file_system_spec.rb
195
196
  - spec/integration/chefignore_spec.rb