knife-essentials 1.3 → 1.3.2

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.
@@ -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