diff --git a/lib/chef-vault/item_keys.rb b/lib/chef-vault/item_keys.rb index c54a273d..1c97c915 100644 --- a/lib/chef-vault/item_keys.rb +++ b/lib/chef-vault/item_keys.rb @@ -185,6 +185,16 @@ def save(item_id = @raw_data["id"]) skey.save end end + else + # Look for sparse keys that need to be moved to default format + skeys = {} + sparse_keys.each do |id| + item = Chef::DataBagItem.load(data_bag, id) + actor, key = item.raw_data.find { |k, _| k != "id" } + skeys[actor] = key + item.destroy(data_bag, id) + end + @raw_data.merge!(skeys) end # save raw data @@ -209,9 +219,7 @@ def destroy nil else # destroy all sparse keys - rgx = Regexp.new("^#{sparse_id(".*")}") - items = Chef::DataBag.load(data_bag).keys.select { |item| item =~ rgx } - items.each do |id| + sparse_keys.each do |id| Chef::DataBagItem.from_hash("data_bag" => data_bag, "id" => id) .destroy(data_bag, id) end @@ -255,6 +263,11 @@ def sparse? @raw_data["mode"] == "sparse" end + def sparse_keys + rgx = Regexp.new("^#{sparse_id(".*")}") + Chef::DataBag.load(data_bag).keys.select { |item| item =~ rgx } + end + def sparse_id(key, item_id = @raw_data["id"]) "#{item_id.chomp("_keys")}_key_#{key}" end diff --git a/spec/chef-vault/item_keys_spec.rb b/spec/chef-vault/item_keys_spec.rb index 58361959..b61d4492 100644 --- a/spec/chef-vault/item_keys_spec.rb +++ b/spec/chef-vault/item_keys_spec.rb @@ -135,6 +135,23 @@ keys.mode("default") end + it "should save the key data in default mode from sparse mode" do + keys.add(chef_key, shared_secret) + keys.mode("sparse") + keys.save("bar") + expect(Chef::DataBagItem.load("foo", "bar_key_client_name").to_hash).to include("id" => "bar_key_client_name") + expect(keys[client_name]).not_to be_empty + keys.mode("default") + keys.save("bar") + expect(Chef::DataBagItem.load("foo", "bar").to_hash).to include("id" => "bar") + expect { Chef::DataBagItem.load("foo", "bar_key_client_name") }.to raise_error(Net::HTTPClientException) + expect(keys[client_name]).not_to be_empty + keys.delete(chef_key) + keys.save("bar") + expect(keys[client_name]).to be_nil + keys.mode("default") + end + it "should remove key data in sparse mode" do keys.add(chef_key, shared_secret) keys.save("bar")