diff options
author | John Keiser <john@johnkeiser.com> | 2016-01-14 15:01:28 -0800 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2016-01-15 15:04:13 -0800 |
commit | ad8d59faaf5bbe35f34889a262c290197c79b09d (patch) | |
tree | 3b7702d0b3ccb2f440fcf8a761c753ea8561bb41 /lib | |
parent | 75fe2f489e3ff3bfbf78df02c5ae2e17c07cc974 (diff) | |
download | chef-ad8d59faaf5bbe35f34889a262c290197c79b09d.tar.gz |
Make local mode respect policies
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/chef_fs/chef_fs_data_store.rb | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/lib/chef/chef_fs/chef_fs_data_store.rb b/lib/chef/chef_fs/chef_fs_data_store.rb index 99a668d50d..46c8c973b0 100644 --- a/lib/chef/chef_fs/chef_fs_data_store.rb +++ b/lib/chef/chef_fs/chef_fs_data_store.rb @@ -188,10 +188,23 @@ class Chef elsif path[0] == "cookbooks" && path.length == 2 # Do nothing. The entry gets created when the cookbook is created. + # /policy_groups/GROUP/policies/NAME + elsif path[0] == "policy_groups" && path[2] == "policies" + # Just set or create the proper entry in the hash + update_json(to_chef_fs_path(path[0..1]), {}, *options) do |group| + if policies.has_key?(path[3]) + raise ChefZero::DataStore::DataAlreadyExistsError.new(path, group) + end + + group["policies"] ||= {} + group["policies"][path[3]] = { "revision_id" => Chef::JSONCompat.parse(data) } + group + end + # create [/organizations/ORG]/users/NAME (with content '{}') # Manipulate the `members.json` file that contains a list of all users elsif is_org? && path == [ "users" ] - update_json("members.json", []) do |members| + update_json("members.json", [], *options) do |members| # Format of each entry: { "user": { "username": "jkeiser" } } if members.any? { |member| member["user"]["username"] == name } raise ChefZero::DataStore::DataAlreadyExistsError.new(path, entry) @@ -204,7 +217,7 @@ class Chef # create [/organizations/ORG]/association_requests/NAME (with content '{}') # Manipulate the `invitations.json` file that contains a list of all users elsif is_org? && path == [ "association_requests" ] - update_json("invitations.json", []) do |invitations| + update_json("invitations.json", [], *options) do |invitations| # Format of each entry: { "id" => "jkeiser-chef", 'username' => 'jkeiser' } if invitations.any? { |member| member["username"] == name } raise ChefZero::DataStore::DataAlreadyExistsError.new(path) @@ -243,19 +256,18 @@ class Chef # /policy_groups/NAME/policies/POLICYNAME: return the revision of the given policy elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 4 - with_entry(path[0..1]) do |entry| - policy_group = Chef::JSONCompat.parse(entry) - if !policy_group["policies"] || !policy_group["policies"][path[3]] || !policy_group["policies"][path[3]] - raise ChefZero::DataStore::DataNotFoundError.new(path, entry) - end - # The policy group looks like: - # { - # "policies": { - # "x": { "revision_id": "10" } - # } - # } - Chef::JSONCompat.to_json_pretty(policy_group["policies"][path[3]]["revision_id"]) + # Just set or create the proper entry in the hash + policy_group = get_json(to_chef_fs_path(path[0..1]), {}) + if !policy_group["policies"] || !policy_group["policies"][path[3]] + raise ChefZero::DataStore::DataNotFoundError.new(path, entry) end + # The policy group looks like: + # { + # "policies": { + # "x": { "revision_id": "10" } + # } + # } + Chef::JSONCompat.to_json_pretty(policy_group["policies"][path[3]]["revision_id"]) # GET [/organizations/ORG]/users/NAME -> /users/NAME # Manipulates members.json @@ -326,6 +338,16 @@ class Chef # Write out the files! if path[0] == "cookbooks" && path.length == 3 write_cookbook(path, data, *options) + + # Handle /policy_groups/some_policy_group/policies/some_policy_name + elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 4 + # Just set or create the proper entry in the hash + update_json(to_chef_fs_path(path[0..1]), {}, *options) do |group| + group["policies"] ||= {} + group["policies"][path[3]] = { "revision_id" => Chef::JSONCompat.parse(data) } + group + end + else with_dir(path[0..-2]) do |parent| child = parent.child(chef_fs_filename(path)) @@ -343,6 +365,16 @@ class Chef if use_memory_store?(path) @memory_store.delete(path) + # DELETE /policy_groups/GROUP/policies/POLICY + elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 4 + update_json(to_chef_fs_path(path[0..1]), {}) do |group| + unless group["policies"] && group["policies"].has_key?(path[3]) + raise ChefZero::DataStore::DataNotFoundError.new(path) + end + group["policies"].delete(path[3]) + group + end + # DELETE [/organizations/ORG]/users/NAME # Manipulates members.json elsif is_org? && path[0] == "users" && path.length == 2 @@ -404,9 +436,9 @@ class Chef end elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 3 - with_entry([ "policy_groups", path[1] ]) do |entry| - policy_group = Chef::JSONCompat.parse(entry.read) - (policy_group["policies"] || {}).keys + with_entry(path[0..1]) do |entry| + policies = Chef::JSONCompat.parse(entry.read)["policies"] || {} + policies.keys end elsif path[0] == "cookbooks" && path.length == 1 @@ -468,6 +500,12 @@ class Chef def exists?(path) if use_memory_store?(path) @memory_store.exists?(path) + + # /policy_groups/NAME/policies/POLICYNAME + elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 4 + group = get_json(to_chef_fs_path(path[0..1]), {}) + group["policies"] && group["policies"].has_key?(path[3]) + else path_always_exists?(path) || Chef::ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists? end @@ -481,9 +519,6 @@ class Chef # /policy_groups/NAME/policies elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 3 exists_dir?(path[0..1]) - # /policy_groups/NAME/policies/POLICYNAME - elsif path[0] == "policy_groups" && path[2] == "policies" && path.length == 4 - exists_dir?(path[0..1]) && list(path[0..2]).include?(path[3]) else Chef::ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists? end @@ -550,11 +585,17 @@ class Chef if path.length >= 3 path[2] = "#{path[2]}.json" end + elsif path[0] == "policies" path = path.dup - if path.length >= 3 - path[2] = "#{path[2]}.json" + if path[2] == "revisions" + # Get rid of "revisions" + path.delete_at(2) + if path.length >= 3 + path[2] = "#{path[2]}.json" + end end + elsif path[0] == "cookbooks" if path.length == 2 raise ChefZero::DataStore::DataNotFoundError.new(path) @@ -618,6 +659,12 @@ class Chef end end + elsif path[0] == "policies" + if path.length >= 3 + path[2] = path[2][0..-6] + path = path[0..1] + [ "revisions" ] + path[2..-1] + end + elsif path.length == 2 && path[0] != "cookbooks" path = path.dup path[1] = path[1][0..-6] @@ -671,16 +718,27 @@ class Chef metadata[:version] || "0.0.0" end - def update_json(path, default_value) + def update_json(path, default_value, *options) entry = Chef::ChefFS::FileSystem.resolve_path(chef_fs, path) begin input = Chef::JSONCompat.parse(entry.read) - output = yield input.dup - entry.write(Chef::JSONCompat.to_json_pretty(output)) if output != input + output = yield input + entry.write(Chef::JSONCompat.to_json_pretty(output)) if output != Chef::JSONCompat.parse(entry.read) rescue Chef::ChefFS::FileSystem::NotFoundError # Send the default value to the caller, and create the entry if the caller updates it output = yield default_value - entry.parent.create_child(entry.name, Chef::JSONCompat.to_json_pretty(output)) if output != [] + parent = entry.parent + parent = ensure_dir(parent) if options.include?(:create_dir) + parent.create_child(entry.name, Chef::JSONCompat.to_json_pretty(output)) if output != [] + end + end + + def ensure_dir(entry) + return entry if entry.exists? + parent = entry.parent + if parent + ensure_dir(parent) + parent.create_child(entry.name) end end |