berkshelf / ridley

A reliable Chef API client with a clean syntax
Other
231 stars 84 forks source link

Reading databag items with `.all` does not work correctly #355

Closed rylarson closed 7 years ago

rylarson commented 8 years ago

I noticed some strange behavior today. Ridley appears to only return the id of the data bag item when you call data_bag.item.all. When you use data_bag.item.find(), it works as expected and returns the entire data bag item.

Here is how to reproduce using chef-zero and the default chef-zero knife.rb config:

$ chef-zero&
[1] 9344
$ >> Starting Chef Zero (v4.9.0)...
>> WEBrick (v1.3.1) on Rack (v1.6.4) is listening at http://127.0.0.1:8889
>> Press CTRL+C to stop

$ cat item1.json 
{
  "id": "item1",
  "name": "name"
}

$ knife data bag create test -c test/knife.rb
Created data_bag[test]
$ knife data bag from file test item1.json -c test/knife.rb
Updated data_bag_item[test::item1]
$ knife data bag list -c test/knife.rb
test

$ knife data bag show test -c test/knife.rb
item1

$ knife data bag show test item1 -c test/knife.rb
WARNING: Unencrypted data bag detected, ignoring any provided secret options.
id:   item1
name: name

$ irb
2.3.1 :001 > require 'ridley'
 => true 
2.3.1 :002 >   chef_server = Ridley.from_chef_config('test/knife.rb')
 2.3.1 :003 > chef_server.data_bag.all
 => [#<Ridley::DataBagObject chef_id:test, attributes:#<VariaModel::Attributes name="test">>] 
2.3.1 :004 > chef_server.data_bag.all[0]
 => #<Ridley::DataBagObject chef_id:test, attributes:#<VariaModel::Attributes name="test">> 
2.3.1 :005 > chef_server.data_bag.all[0].item.all
 => [#<Ridley::DataBagItemObject chef_id:item1, attributes:#<VariaModel::Attributes id="item1">>] 
2.3.1 :006 > chef_server.data_bag.all[0].item.all[0]
 => #<Ridley::DataBagItemObject chef_id:item1, attributes:#<VariaModel::Attributes id="item1">> 
2.3.1 :007 > chef_server.data_bag.all[0].item.all[0]['id']
 => "item1" 
2.3.1 :008 > chef_server.data_bag.all[0].item.all[0]['name']
 => nil 
2.3.1 :009 > chef_server.data_bag.all[0].item.find('item1')
 => #<Ridley::DataBagItemObject chef_id:item1, attributes:#<VariaModel::Attributes id="item1" name="name">> 
2.3.1 :010 > chef_server.data_bag.all[0].item.find('item1')['name']
 => "name" 
thommay commented 7 years ago

So this is pretty core to how ridley was built - that it will try and make as few calls as possible so as to not block your application. So I'm going to close this as working as intended.

rylarson commented 7 years ago

If you call all on a data bag item, how does it make any sense for it to return a completely invalid object where the fields are all nil except for id? How is the data bag item case any different from any other Chef API resource? I don't think any sane person would consider this expected behavior.