summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2016-03-02 16:39:00 +0000
committerThom May <thom@chef.io>2016-03-02 16:39:00 +0000
commitf68bf3c899ea68f6fbc4ab95bb6c6117e9aec147 (patch)
tree52089ee0debd68a04620b32075ca378687e4e13c
parentbe1438e82d3fc6dfd85eaf24402283dec765de32 (diff)
downloadchef-tm/ruby_zero_roles.tar.gz
read roles from ruby filestm/ruby_zero_roles
-rw-r--r--lib/chef/chef_fs/data_handler/data_handler_base.rb2
-rw-r--r--lib/chef/chef_fs/data_handler/role_data_handler.rb8
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb3
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/environments_dir.rb4
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/role_entry.rb59
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/roles_dir.rb51
-rw-r--r--lib/chef/chef_fs/file_system/repository/chef_repository_file_system_roles_dir.rb45
-rw-r--r--lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb5
-rw-r--r--lib/chef/chef_fs/file_system/repository/ruby_or_json_file.rb84
-rw-r--r--spec/integration/knife/upload_spec.rb18
10 files changed, 274 insertions, 5 deletions
diff --git a/lib/chef/chef_fs/data_handler/data_handler_base.rb b/lib/chef/chef_fs/data_handler/data_handler_base.rb
index 83f56ed16d..863efa6bd0 100644
--- a/lib/chef/chef_fs/data_handler/data_handler_base.rb
+++ b/lib/chef/chef_fs/data_handler/data_handler_base.rb
@@ -190,7 +190,7 @@ class Chef
# Calls the on_error block with the error, if there is one.
#
def verify_integrity(object, entry, &on_error)
- base_name = remove_dot_json(entry.name)
+ base_name = File.basename(entry.name, ".*")
if object["name"] != base_name
on_error.call("Name must be '#{base_name}' (is '#{object['name']}')")
end
diff --git a/lib/chef/chef_fs/data_handler/role_data_handler.rb b/lib/chef/chef_fs/data_handler/role_data_handler.rb
index 74533cff05..56de519a3e 100644
--- a/lib/chef/chef_fs/data_handler/role_data_handler.rb
+++ b/lib/chef/chef_fs/data_handler/role_data_handler.rb
@@ -7,7 +7,7 @@ class Chef
class RoleDataHandler < DataHandlerBase
def normalize(role, entry)
result = normalize_hash(role, {
- "name" => remove_dot_json(entry.name),
+ "name" => File.basename(entry.name, ".*"),
"description" => "",
"json_class" => "Chef::Role",
"chef_type" => "role",
@@ -31,6 +31,12 @@ class Chef
Chef::Role
end
+ def from_ruby(path)
+ r = Chef::Role.new
+ r.from_file(path)
+ r.to_hash
+ end
+
def to_ruby(object)
to_ruby_keys(object, %w{name description default_attributes override_attributes run_list env_run_lists})
end
diff --git a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
index 6c99d6de73..b5a651ad1a 100644
--- a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
@@ -31,6 +31,7 @@ require "chef/chef_fs/file_system/chef_server/organization_members_entry"
require "chef/chef_fs/file_system/chef_server/policies_dir"
require "chef/chef_fs/file_system/chef_server/policy_groups_dir"
require "chef/chef_fs/file_system/chef_server/environments_dir"
+require "chef/chef_fs/file_system/chef_server/roles_dir"
require "chef/chef_fs/data_handler/acl_data_handler"
require "chef/chef_fs/data_handler/client_data_handler"
require "chef/chef_fs/data_handler/environment_data_handler"
@@ -149,7 +150,7 @@ class Chef
# /environments
EnvironmentsDir.new("environments", self, nil, Chef::ChefFS::DataHandler::EnvironmentDataHandler.new),
# /roles
- RestListDir.new("roles", self, nil, Chef::ChefFS::DataHandler::RoleDataHandler.new),
+ RolesDir.new("roles", self, nil, Chef::ChefFS::DataHandler::RoleDataHandler.new),
]
if repo_mode == "hosted_everything"
result += [
diff --git a/lib/chef/chef_fs/file_system/chef_server/environments_dir.rb b/lib/chef/chef_fs/file_system/chef_server/environments_dir.rb
index 494036931f..2b8a400435 100644
--- a/lib/chef/chef_fs/file_system/chef_server/environments_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/environments_dir.rb
@@ -34,6 +34,10 @@ class Chef
end
end
+ def can_have_child?(name, is_dir)
+ %w{ .rb .json }.include?(File.extname(name)) && !is_dir
+ end
+
class DefaultEnvironmentEntry < RestListEntry
def initialize(name, parent, exists = nil)
super(name, parent)
diff --git a/lib/chef/chef_fs/file_system/chef_server/role_entry.rb b/lib/chef/chef_fs/file_system/chef_server/role_entry.rb
new file mode 100644
index 0000000000..1d4cd4bf5d
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/chef_server/role_entry.rb
@@ -0,0 +1,59 @@
+#
+# Author:: John Keiser (<jkeiser@chef.io>)
+# Copyright:: Copyright 2013-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/chef_fs/file_system/chef_server/rest_list_entry"
+require "chef/chef_fs/file_system/not_found_error"
+require "chef/chef_fs/file_system/operation_not_allowed_error"
+require "chef/chef_fs/file_system/operation_failed_error"
+
+class Chef
+ module ChefFS
+ module FileSystem
+ module ChefServer
+ class RoleEntry < RestListEntry
+
+ def api_child_name
+ raise "Invalid name #{name}" unless %w{ .rb .json}.include? File.extname(name)
+ File.basename(name, ".*")
+ end
+
+ def child_name(name)
+ if File.extname(name) == ".rb"
+ name.gsub(/.rb$/, ".json")
+ else
+ name
+ end
+ end
+
+ def exists?
+ cn = child_name(name)
+ if @exists.nil?
+ begin
+ @exists = parent.children.any? { |child| child.name == cn }
+ rescue Chef::ChefFS::FileSystem::NotFoundError
+ @exists = false
+ end
+ end
+ @exists
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/chef_fs/file_system/chef_server/roles_dir.rb b/lib/chef/chef_fs/file_system/chef_server/roles_dir.rb
new file mode 100644
index 0000000000..707b5424c8
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/chef_server/roles_dir.rb
@@ -0,0 +1,51 @@
+#
+# Author:: John Keiser (<jkeiser@chef.io>)
+# Copyright:: Copyright 2012-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/chef_fs/file_system/base_fs_dir"
+require "chef/chef_fs/file_system/chef_server/rest_list_dir"
+require "chef/chef_fs/file_system/chef_server/role_entry"
+require "chef/chef_fs/file_system/not_found_error"
+
+class Chef
+ module ChefFS
+ module FileSystem
+ module ChefServer
+ class RolesDir < RestListDir
+ def can_have_child?(name, is_dir)
+ %w{ .rb .json }.include?(File.extname(name)) && !is_dir
+ end
+
+ def child_name(name)
+ if File.extname(name) == ".rb"
+ name.gsub(/.rb$/, ".json")
+ else
+ name
+ end
+ end
+
+ def make_child_entry(name, exists = nil)
+ cn = child_name(name)
+ @children.select { |child| child.name == cn }.first if @children
+ RoleEntry.new(cn, self, exists)
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_roles_dir.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_roles_dir.rb
new file mode 100644
index 0000000000..e8e3ee07e2
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_roles_dir.rb
@@ -0,0 +1,45 @@
+#
+# Author:: Jordan Running (<jr@chef.io>)
+# Copyright:: Copyright 2013-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/chef_fs/file_system/repository/chef_repository_file_system_entry"
+require "chef/chef_fs/file_system/repository/ruby_or_json_file.rb"
+require "chef/chef_fs/data_handler/role_data_handler"
+
+class Chef
+ module ChefFS
+ module FileSystem
+ module Repository
+ class ChefRepositoryFileSystemRolesDir < ChefRepositoryFileSystemEntry
+ def initialize(name, parent, path = nil)
+ super(name, parent, path, Chef::ChefFS::DataHandler::RoleDataHandler.new)
+ end
+
+ def can_have_child?(name, is_dir)
+ %w{ .rb .json }.include?(File.extname(name)) && !is_dir
+ end
+
+ protected
+ def make_child_entry(child_name)
+ RubyOrJsonFile.new(child_name, self)
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
index c7209ba634..72bb402ab5 100644
--- a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
@@ -22,6 +22,7 @@ require "chef/chef_fs/file_system/repository/cookbooks_dir"
require "chef/chef_fs/file_system/repository/cookbook_artifacts_dir"
require "chef/chef_fs/file_system/repository/data_bags_dir"
require "chef/chef_fs/file_system/repository/chef_repository_file_system_client_keys_dir"
+require "chef/chef_fs/file_system/repository/chef_repository_file_system_roles_dir"
require "chef/chef_fs/file_system/repository/chef_repository_file_system_entry"
require "chef/chef_fs/file_system/repository/chef_repository_file_system_policies_dir"
require "chef/chef_fs/file_system/repository/versioned_cookbooks_dir"
@@ -182,6 +183,8 @@ class Chef
dirs = paths.map { |path| ChefRepositoryFileSystemAclsDir.new(name, self, path) }
when "client_keys"
dirs = paths.map { |path| ChefRepositoryFileSystemClientKeysDir.new(name, self, path) }
+ when "roles"
+ dirs = paths.map { |path| ChefRepositoryFileSystemRolesDir.new(name, self, path) }
else
data_handler = case name
when "clients"
@@ -192,8 +195,6 @@ class Chef
Chef::ChefFS::DataHandler::NodeDataHandler.new
when "policy_groups"
Chef::ChefFS::DataHandler::PolicyGroupDataHandler.new
- when "roles"
- Chef::ChefFS::DataHandler::RoleDataHandler.new
when "users"
Chef::ChefFS::DataHandler::UserDataHandler.new
when "groups"
diff --git a/lib/chef/chef_fs/file_system/repository/ruby_or_json_file.rb b/lib/chef/chef_fs/file_system/repository/ruby_or_json_file.rb
new file mode 100644
index 0000000000..2e6644e34f
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/repository/ruby_or_json_file.rb
@@ -0,0 +1,84 @@
+#
+# Author:: Thom May (<thom@chef.io>)
+# Copyright:: Copyright 2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/chef_fs/data_handler/role_data_handler"
+class Chef
+ module ChefFS
+ module FileSystem
+ module Repository
+ class RubyOrJsonFile < ChefRepositoryFileSystemEntry
+ attr_reader :name
+ attr_reader :parent
+ attr_reader :path
+ attr_reader :file_path
+ attr_reader :data_handler
+
+ def initialize(name, parent)
+ @parent = parent
+ @name = name
+ @path = Chef::ChefFS::PathUtils.join(parent.path, name)
+ @data_handler = parent.data_handler
+ @file_path = "#{parent.file_path}/#{name}"
+ end
+
+ def name_valid?
+ !name.start_with?(".") && %w{ .rb .json }.include?(File.extname(name))
+ end
+
+ def fs_entry_valid?
+ name_valid? && File.file?(file_path)
+ end
+
+ def create(file_contents)
+ if exists?
+ raise Chef::ChefFS::FileSystem::AlreadyExistsError.new(:create_child, self)
+ else
+ write(file_contents)
+ end
+ end
+
+ def can_have_child?(name, is_dir)
+ false
+ end
+
+ def path_for_printing
+ file_path
+ end
+
+ def read
+ if File.extname(file_path) == ".rb"
+ data_handler.from_ruby(file_path).to_json
+ else
+ File.read(file_path)
+ end
+ rescue Errno::ENOENT
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
+
+ def root
+ parent.root
+ end
+
+ def compare_to(other)
+ nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb
index 739dfa44d1..708cc8f04c 100644
--- a/spec/integration/knife/upload_spec.rb
+++ b/spec/integration/knife/upload_spec.rb
@@ -154,6 +154,24 @@ EOM
end
end
+ context "the role is in ruby" do
+ before do
+ file "roles/x.rb", <<EOM
+name "x"
+description "blarghle"
+EOM
+ end
+
+ it "knife upload changes the role" do
+ knife("upload /").should_succeed "Updated /roles/x.json\n"
+ knife("diff --name-status /").should_succeed ""
+ end
+ it "knife upload --no-diff does not change the role" do
+ knife("upload --no-diff /").should_succeed ""
+ knife("diff --name-status /").should_succeed "M\t/roles/x.rb\n"
+ end
+ end
+
context "when cookbook metadata has a self-dependency" do
before do
file "cookbooks/x/metadata.rb", "name 'x'; version '1.0.0'; depends 'x'"