summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/api_client/registration.rb4
-rw-r--r--lib/chef/application.rb6
-rw-r--r--lib/chef/application/windows_service.rb4
-rw-r--r--lib/chef/audit/audit_reporter.rb4
-rw-r--r--lib/chef/chef_fs/file_system/chef_server_root_dir.rb2
-rw-r--r--lib/chef/client.rb9
-rw-r--r--lib/chef/cookbook/remote_file_vendor.rb2
-rw-r--r--lib/chef/cookbook/synchronizer.rb5
-rw-r--r--lib/chef/cookbook_loader.rb2
-rw-r--r--lib/chef/cookbook_uploader.rb5
-rw-r--r--lib/chef/cookbook_version.rb30
-rw-r--r--lib/chef/data_bag.rb19
-rw-r--r--lib/chef/data_bag_item.rb36
-rw-r--r--lib/chef/environment.rb23
-rw-r--r--lib/chef/formatters/minimal.rb2
-rw-r--r--lib/chef/guard_interpreter/resource_guard_interpreter.rb2
-rw-r--r--lib/chef/http.rb2
-rw-r--r--lib/chef/http/http_request.rb2
-rw-r--r--lib/chef/http/simple.rb18
-rw-r--r--lib/chef/http/simple_json.rb43
-rw-r--r--lib/chef/key.rb21
-rw-r--r--lib/chef/knife.rb14
-rw-r--r--lib/chef/knife/bootstrap/client_builder.rb12
-rw-r--r--lib/chef/knife/cookbook_bulk_delete.rb4
-rw-r--r--lib/chef/knife/cookbook_delete.rb4
-rw-r--r--lib/chef/knife/cookbook_download.rb5
-rw-r--r--lib/chef/knife/cookbook_list.rb2
-rw-r--r--lib/chef/knife/cookbook_show.rb10
-rw-r--r--lib/chef/knife/cookbook_site_download.rb6
-rw-r--r--lib/chef/knife/cookbook_site_list.rb2
-rw-r--r--lib/chef/knife/cookbook_site_search.rb2
-rw-r--r--lib/chef/knife/cookbook_site_share.rb2
-rw-r--r--lib/chef/knife/cookbook_site_show.rb6
-rw-r--r--lib/chef/knife/cookbook_site_unshare.rb2
-rw-r--r--lib/chef/knife/data_bag_create.rb4
-rw-r--r--lib/chef/knife/data_bag_delete.rb4
-rw-r--r--lib/chef/knife/data_bag_edit.rb2
-rw-r--r--lib/chef/knife/environment_compare.rb2
-rw-r--r--lib/chef/knife/index_rebuild.rb4
-rw-r--r--lib/chef/knife/raw.rb1
-rw-r--r--lib/chef/knife/recipe_list.rb2
-rw-r--r--lib/chef/knife/status.rb4
-rw-r--r--lib/chef/mixin/securable.rb2
-rw-r--r--lib/chef/node.rb36
-rw-r--r--lib/chef/org.rb20
-rw-r--r--lib/chef/platform/provider_mapping.rb2
-rw-r--r--lib/chef/policy_builder/dynamic.rb1
-rw-r--r--lib/chef/policy_builder/expand_node_object.rb11
-rw-r--r--lib/chef/policy_builder/policyfile.rb4
-rw-r--r--lib/chef/provider.rb6
-rw-r--r--lib/chef/provider/deploy.rb2
-rw-r--r--lib/chef/provider/dsc_resource.rb2
-rw-r--r--lib/chef/provider/dsc_script.rb2
-rw-r--r--lib/chef/provider/env.rb6
-rw-r--r--lib/chef/provider/group/aix.rb2
-rw-r--r--lib/chef/provider/group/groupadd.rb8
-rw-r--r--lib/chef/provider/group/usermod.rb8
-rw-r--r--lib/chef/provider/link.rb2
-rw-r--r--lib/chef/provider/mount.rb14
-rw-r--r--lib/chef/provider/osx_profile.rb2
-rw-r--r--lib/chef/provider/package.rb12
-rw-r--r--lib/chef/provider/package/chocolatey.rb246
-rw-r--r--lib/chef/provider/package/rubygems.rb4
-rw-r--r--lib/chef/provider/package/windows.rb2
-rw-r--r--lib/chef/provider/package/windows/exe.rb14
-rw-r--r--lib/chef/provider/remote_file/content.rb2
-rw-r--r--lib/chef/provider/service.rb14
-rw-r--r--lib/chef/provider/service/macosx.rb2
-rw-r--r--lib/chef/provider/service/simple.rb8
-rw-r--r--lib/chef/provider/service/windows.rb69
-rw-r--r--lib/chef/providers.rb3
-rw-r--r--lib/chef/resource.rb4
-rw-r--r--lib/chef/resource/chocolatey_package.rb39
-rw-r--r--lib/chef/resource/cron.rb2
-rw-r--r--lib/chef/resource/dsc_resource.rb240
-rw-r--r--lib/chef/resource/file/verification.rb2
-rw-r--r--lib/chef/resource/windows_script.rb2
-rw-r--r--lib/chef/resource_definition.rb2
-rw-r--r--lib/chef/resource_reporter.rb7
-rw-r--r--lib/chef/resources.rb3
-rw-r--r--lib/chef/role.rb28
-rw-r--r--lib/chef/run_list/run_list_expansion.rb8
-rw-r--r--lib/chef/search/query.rb22
-rw-r--r--lib/chef/server_api.rb26
-rw-r--r--lib/chef/shell/ext.rb6
-rw-r--r--lib/chef/shell/shell_rest.rb28
-rw-r--r--lib/chef/shell/shell_session.rb5
-rw-r--r--lib/chef/user_v1.rb6
-rw-r--r--lib/chef/util/dsc/configuration_generator.rb2
-rw-r--r--lib/chef/util/powershell/cmdlet.rb6
-rw-r--r--lib/chef/version/platform.rb2
-rw-r--r--lib/chef/version_class.rb2
-rw-r--r--lib/chef/version_constraint.rb2
-rw-r--r--lib/chef/win32/api.rb7
-rw-r--r--lib/chef/win32/api/security.rb38
-rw-r--r--lib/chef/win32/error.rb3
-rw-r--r--lib/chef/win32/security.rb63
97 files changed, 918 insertions, 478 deletions
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb
index bc941d5bfa..99667acc0a 100644
--- a/lib/chef/api_client/registration.rb
+++ b/lib/chef/api_client/registration.rb
@@ -17,7 +17,7 @@
#
require 'chef/config'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/exceptions'
class Chef
@@ -45,7 +45,7 @@ class Chef
#--
# If client creation fails with a 5xx, it is retried up to 5 times. These
# retries are on top of the retries with randomized exponential backoff
- # built in to Chef::REST. The retries here are a workaround for failures
+ # built in to Chef::ServerAPI. The retries here are a workaround for failures
# caused by resource contention in Hosted Chef when creating a very large
# number of clients simultaneously, (e.g., spinning up 100s of ec2 nodes
# at once). Future improvements to the affected component should make
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 0ee201f103..3ab68260d7 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -186,12 +186,12 @@ class Chef
# Called prior to starting the application, by the run method
def setup_application
- raise Chef::Exceptions::Application, "#{self.to_s}: you must override setup_application"
+ raise Chef::Exceptions::Application, "#{self}: you must override setup_application"
end
# Actually run the application
def run_application
- raise Chef::Exceptions::Application, "#{self.to_s}: you must override run_application"
+ raise Chef::Exceptions::Application, "#{self}: you must override run_application"
end
# Initializes Chef::Client instance and runs it
@@ -307,7 +307,7 @@ class Chef
class << self
def debug_stacktrace(e)
message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
- chef_stacktrace_out = "Generated at #{Time.now.to_s}\n"
+ chef_stacktrace_out = "Generated at #{Time.now}\n"
chef_stacktrace_out += message
Chef::FileCache.store("chef-stacktrace.out", chef_stacktrace_out)
diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb
index 2f938059ca..9becf4b33f 100644
--- a/lib/chef/application/windows_service.rb
+++ b/lib/chef/application/windows_service.rb
@@ -23,7 +23,7 @@ require 'chef/client'
require 'chef/config'
require 'chef/handler/error_report'
require 'chef/log'
-require 'chef/rest'
+require 'chef/http'
require 'mixlib/cli'
require 'socket'
require 'uri'
@@ -308,7 +308,7 @@ class Chef
begin
case config[:config_file]
when /^(http|https):\/\//
- Chef::REST.new("", nil, nil).fetch(config[:config_file]) { |f| apply_config(f.path) }
+ Chef::HTTP.new("").streaming_request(config[:config_file]) { |f| apply_config(f.path) }
else
::File::open(config[:config_file]) { |f| apply_config(f.path) }
end
diff --git a/lib/chef/audit/audit_reporter.rb b/lib/chef/audit/audit_reporter.rb
index d952d8a249..face24f1f5 100644
--- a/lib/chef/audit/audit_reporter.rb
+++ b/lib/chef/audit/audit_reporter.rb
@@ -127,10 +127,8 @@ class Chef
end
Chef::Log.debug "Audit Report:\n#{Chef::JSONCompat.to_json_pretty(run_data)}"
- # Since we're posting compressed data we can not directly call post_rest which expects JSON
begin
- audit_url = rest_client.create_url(audit_history_url)
- rest_client.post(audit_url, run_data, headers)
+ rest_client.post(audit_history_url, run_data, headers)
rescue StandardError => e
if e.respond_to? :response
# 404 error code is OK. This means the version of server we're running against doesn't support
diff --git a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
index 09181ac4b4..badb70ce50 100644
--- a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
@@ -104,7 +104,7 @@ class Chef
end
def chef_rest
- Chef::REST.new(chef_server_url, chef_username, chef_private_key)
+ Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key)
end
def api_path
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 6ac5cecbdf..ead804879f 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -22,7 +22,7 @@ require 'chef/config'
require 'chef/mixin/params_validate'
require 'chef/mixin/path_sanity'
require 'chef/log'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/api_client'
require 'chef/api_client/registration'
require 'chef/audit/runner'
@@ -92,7 +92,7 @@ class Chef
#
# The rest object used to communicate with the Chef server.
#
- # @return [Chef::REST]
+ # @return [Chef::ServerAPI]
#
attr_reader :rest
@@ -575,7 +575,7 @@ class Chef
# If Chef::Config.client_key does not exist, we register the client with the
# Chef server and fire the registration_start and registration_completed events.
#
- # @return [Chef::REST] The server connection object.
+ # @return [Chef::ServerAPI] The server connection object.
#
# @see Chef::Config#chef_server_url
# @see Chef::Config#client_key
@@ -601,7 +601,8 @@ class Chef
events.registration_completed
end
# We now have the client key, and should use it from now on.
- @rest = Chef::REST.new(config[:chef_server_url], client_name, config[:client_key])
+ @rest = Chef::ServerAPI.new(config[:chef_server_url], client_name: client_name,
+ signing_key_filename: config[:client_key])
register_reporters
rescue Exception => e
# TODO this should probably only ever fire if we *started* registration.
diff --git a/lib/chef/cookbook/remote_file_vendor.rb b/lib/chef/cookbook/remote_file_vendor.rb
index 7868430227..b118c75f9e 100644
--- a/lib/chef/cookbook/remote_file_vendor.rb
+++ b/lib/chef/cookbook/remote_file_vendor.rb
@@ -63,7 +63,7 @@ class Chef
# (remote, per manifest), do the update. This will also execute if there
# is no current checksum.
if current_checksum != found_manifest_record['checksum']
- raw_file = @rest.get_rest(found_manifest_record[:url], true)
+ raw_file = @rest.get(found_manifest_record[:url], true)
Chef::Log.debug("Storing updated #{cache_filename} in the cache.")
Chef::FileCache.move_to(raw_file.path, cache_filename)
diff --git a/lib/chef/cookbook/synchronizer.rb b/lib/chef/cookbook/synchronizer.rb
index fc8e739d73..b499963653 100644
--- a/lib/chef/cookbook/synchronizer.rb
+++ b/lib/chef/cookbook/synchronizer.rb
@@ -1,5 +1,6 @@
require 'chef/client'
require 'chef/util/threaded_job_queue'
+require 'chef/server_api'
require 'singleton'
class Chef
@@ -274,7 +275,7 @@ class Chef
# downloaded to the path +destination+ which is relative to the Chef file
# cache root.
def download_file(url, destination)
- raw_file = server_api.get_rest(url, true)
+ raw_file = server_api.streaming_request(url)
Chef::Log.info("Storing updated #{destination} in the cache.")
cache.move_to(raw_file.path, destination)
@@ -286,7 +287,7 @@ class Chef
end
def server_api
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
end
diff --git a/lib/chef/cookbook_loader.rb b/lib/chef/cookbook_loader.rb
index 79005b1569..e783405b9b 100644
--- a/lib/chef/cookbook_loader.rb
+++ b/lib/chef/cookbook_loader.rb
@@ -106,7 +106,7 @@ class Chef
if @cookbooks_by_name.has_key?(cookbook.to_sym) or load_cookbook(cookbook.to_sym)
@cookbooks_by_name[cookbook.to_sym]
else
- raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook.to_s}; did you forget to add metadata to a cookbook? (https://docs.chef.io/config_rb_metadata.html)"
+ raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook}; did you forget to add metadata to a cookbook? (https://docs.chef.io/config_rb_metadata.html)"
end
end
diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb
index f24ce2cd56..64a8a4e168 100644
--- a/lib/chef/cookbook_uploader.rb
+++ b/lib/chef/cookbook_uploader.rb
@@ -9,6 +9,7 @@ require 'chef/cookbook/syntax_check'
require 'chef/cookbook/file_system_file_vendor'
require 'chef/util/threaded_job_queue'
require 'chef/sandbox'
+require 'chef/server_api'
class Chef
class CookbookUploader
@@ -31,7 +32,7 @@ class Chef
# uploading the cookbook. This allows frozen CookbookVersion
# documents on the server to be overwritten (otherwise a 409 is
# returned by the server)
- # * :rest A Chef::REST object that you have configured the way you like it.
+ # * :rest A Chef::ServerAPI object that you have configured the way you like it.
# If you don't provide this, one will be created using the values
# in Chef::Config.
# * :concurrency An integer that decided how many threads will be used to
@@ -39,7 +40,7 @@ class Chef
def initialize(cookbooks, opts={})
@opts = opts
@cookbooks = Array(cookbooks)
- @rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
+ @rest = opts[:rest] || Chef::ServerAPI.new(Chef::Config[:chef_server_url])
@concurrency = opts[:concurrency] || 10
@policy_mode = opts[:policy_mode] || false
end
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 0e9617f98c..4eb118d3bc 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -25,6 +25,7 @@ require 'chef/cookbook/metadata'
require 'chef/version_class'
require 'chef/digester'
require 'chef/cookbook_manifest'
+require 'chef/server_api'
class Chef
@@ -459,11 +460,13 @@ class Chef
end
private :preferences_for_path
- def self.json_create(o)
- cookbook_version = new(o["cookbook_name"])
+ def self.from_hash(o)
+ cookbook_version = new(o["cookbook_name"] || o["name"])
+
# We want the Chef::Cookbook::Metadata object to always be inflated
cookbook_version.metadata = Chef::Cookbook::Metadata.from_hash(o["metadata"])
cookbook_version.manifest = o
+ cookbook_version.identifier = o["identifier"] if o.key?("identifier")
# We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(cookbook_version.metadata))
@@ -472,13 +475,12 @@ class Chef
cookbook_version
end
+ def self.json_create(o)
+ from_hash(o)
+ end
+
def self.from_cb_artifact_data(o)
- cookbook_version = new(o["name"])
- # We want the Chef::Cookbook::Metadata object to always be inflated
- cookbook_version.metadata = Chef::Cookbook::Metadata.from_hash(o["metadata"])
- cookbook_version.manifest = o
- cookbook_version.identifier = o["identifier"]
- cookbook_version
+ from_hash(o)
end
# @deprecated This method was used by the Ruby Chef Server and is no longer
@@ -543,22 +545,22 @@ class Chef
end
def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def destroy
- chef_server_rest.delete_rest("cookbooks/#{name}/#{version}")
+ chef_server_rest.delete("cookbooks/#{name}/#{version}")
self
end
def self.load(name, version="_latest")
version = "_latest" if version == "latest"
- chef_server_rest.get_rest("cookbooks/#{name}/#{version}")
+ from_hash(chef_server_rest.get("cookbooks/#{name}/#{version}"))
end
# The API returns only a single version of each cookbook in the result from the cookbooks method
def self.list
- chef_server_rest.get_rest('cookbooks')
+ chef_server_rest.get('cookbooks')
end
# Alias latest_cookbooks as list
@@ -567,7 +569,7 @@ class Chef
end
def self.list_all_versions
- chef_server_rest.get_rest('cookbooks?num_versions=all')
+ chef_server_rest.get('cookbooks?num_versions=all')
end
##
@@ -577,7 +579,7 @@ class Chef
# [String]:: Array of cookbook versions, which are strings like 'x.y.z'
# nil:: if the cookbook doesn't exist. an error will also be logged.
def self.available_versions(cookbook_name)
- chef_server_rest.get_rest("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map do |cb|
+ chef_server_rest.get("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map do |cb|
cb["version"]
end
rescue Net::HTTPServerException => e
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index 401ba6f63f..9d0dc53da5 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -24,6 +24,7 @@ require 'chef/mixin/from_file'
require 'chef/data_bag_item'
require 'chef/mash'
require 'chef/json_compat'
+require 'chef/server_api'
class Chef
class DataBag
@@ -70,15 +71,19 @@ class Chef
end
def chef_server_rest
- @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
# Create a Chef::Role from JSON
def self.json_create(o)
+ from_hash(o)
+ end
+
+ def self.from_hash(o)
bag = new
bag.name(o["name"])
bag
@@ -104,7 +109,7 @@ class Chef
response
end
else
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data")
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("data")
end
end
end
@@ -120,7 +125,7 @@ class Chef
end
Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path, name.to_s), "*.json")).inject({}) do |bag, f|
- item = Chef::JSONCompat.from_json(IO.read(f))
+ item = Chef::JSONCompat.parse(IO.read(f))
# Check if we have multiple items with similar names (ids) and raise if their content differs
if data_bag.has_key?(item["id"]) && data_bag[item["id"]] != item
@@ -132,12 +137,12 @@ class Chef
end
return data_bag
else
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data/#{name}")
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("data/#{name}")
end
end
def destroy
- chef_server_rest.delete_rest("data/#{@name}")
+ chef_server_rest.delete("data/#{@name}")
end
# Save the Data Bag via RESTful API
@@ -156,7 +161,7 @@ class Chef
#create a data bag via RESTful API
def create
- chef_server_rest.post_rest("data", self)
+ chef_server_rest.post("data", self)
self
end
diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb
index 31c9b69330..7ef9fffe07 100644
--- a/lib/chef/data_bag_item.rb
+++ b/lib/chef/data_bag_item.rb
@@ -25,6 +25,7 @@ require 'chef/mixin/params_validate'
require 'chef/mixin/from_file'
require 'chef/data_bag'
require 'chef/mash'
+require 'chef/server_api'
require 'chef/json_compat'
class Chef
@@ -58,11 +59,11 @@ class Chef
end
def chef_server_rest
- @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def raw_data
@@ -125,22 +126,23 @@ class Chef
end
def self.from_hash(h)
+ h.delete("chef_type")
+ h.delete("json_class")
+ h.delete("name")
+
item = new
- item.raw_data = h
+ item.data_bag(h.delete("data_bag")) if h.key?("data_bag")
+ if h.key?("raw_data")
+ item.raw_data = Mash.new(h["raw_data"])
+ else
+ item.raw_data = h
+ end
item
end
# Create a Chef::DataBagItem from JSON
def self.json_create(o)
- bag_item = new
- bag_item.data_bag(o["data_bag"])
- o.delete("data_bag")
- o.delete("chef_type")
- o.delete("json_class")
- o.delete("name")
-
- bag_item.raw_data = Mash.new(o["raw_data"])
- bag_item
+ from_hash(o)
end
# Load a Data Bag Item by name via either the RESTful API or local data_bag_path if run in solo mode
@@ -149,7 +151,7 @@ class Chef
bag = Chef::DataBag.load(data_bag)
item = bag[name]
else
- item = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data/#{data_bag}/#{name}")
+ item = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("data/#{data_bag}/#{name}")
end
if item.kind_of?(DataBagItem)
@@ -162,7 +164,7 @@ class Chef
end
def destroy(data_bag=data_bag(), databag_item=name)
- chef_server_rest.delete_rest("data/#{data_bag}/#{databag_item}")
+ chef_server_rest.delete("data/#{data_bag}/#{databag_item}")
end
# Save this Data Bag Item via RESTful API
@@ -172,18 +174,18 @@ class Chef
if Chef::Config[:why_run]
Chef::Log.warn("In why-run mode, so NOT performing data bag item save.")
else
- r.put_rest("data/#{data_bag}/#{item_id}", self)
+ r.put("data/#{data_bag}/#{item_id}", self)
end
rescue Net::HTTPServerException => e
raise e unless e.response.code == "404"
- r.post_rest("data/#{data_bag}", self)
+ r.post("data/#{data_bag}", self)
end
self
end
# Create this Data Bag Item via RESTful API
def create
- chef_server_rest.post_rest("data/#{data_bag}", self)
+ chef_server_rest.post("data/#{data_bag}", self)
self
end
diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb
index 7d4b410639..5612978a08 100644
--- a/lib/chef/environment.rb
+++ b/lib/chef/environment.rb
@@ -24,6 +24,7 @@ require 'chef/mash'
require 'chef/mixin/params_validate'
require 'chef/mixin/from_file'
require 'chef/version_constraint'
+require 'chef/server_api'
class Chef
class Environment
@@ -47,11 +48,11 @@ class Chef
end
def chef_server_rest
- @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def name(arg=nil)
@@ -216,6 +217,10 @@ class Chef
end
def self.json_create(o)
+ from_hash(o)
+ end
+
+ def self.from_hash(o)
environment = new
environment.name(o["name"])
environment.description(o["description"])
@@ -233,7 +238,7 @@ class Chef
end
response
else
- chef_server_rest.get_rest("environments")
+ chef_server_rest.get("environments")
end
end
@@ -241,7 +246,7 @@ class Chef
if Chef::Config[:solo]
load_from_file(name)
else
- chef_server_rest.get_rest("environments/#{name}")
+ chef_server_rest.get("environments/#{name}")
end
end
@@ -267,26 +272,26 @@ class Chef
end
def destroy
- chef_server_rest.delete_rest("environments/#{@name}")
+ chef_server_rest.delete("environments/#{@name}")
end
def save
begin
- chef_server_rest.put_rest("environments/#{@name}", self)
+ chef_server_rest.put("environments/#{@name}", self)
rescue Net::HTTPServerException => e
raise e unless e.response.code == "404"
- chef_server_rest.post_rest("environments", self)
+ chef_server_rest.post("environments", self)
end
self
end
def create
- chef_server_rest.post_rest("environments", self)
+ chef_server_rest.post("environments", self)
self
end
def self.load_filtered_recipe_list(environment)
- chef_server_rest.get_rest("environments/#{environment}/recipes")
+ chef_server_rest.get("environments/#{environment}/recipes")
end
def to_s
diff --git a/lib/chef/formatters/minimal.rb b/lib/chef/formatters/minimal.rb
index 3862951f76..62db517e3e 100644
--- a/lib/chef/formatters/minimal.rb
+++ b/lib/chef/formatters/minimal.rb
@@ -157,7 +157,7 @@ class Chef
puts "\n"
puts "resources updated this run:"
updated_resources.each do |resource|
- puts "* #{resource.to_s}"
+ puts "* #{resource}"
updates_by_resource[resource.name].flatten.each do |update|
puts " - #{update}"
end
diff --git a/lib/chef/guard_interpreter/resource_guard_interpreter.rb b/lib/chef/guard_interpreter/resource_guard_interpreter.rb
index 8cff3bc032..a333028a22 100644
--- a/lib/chef/guard_interpreter/resource_guard_interpreter.rb
+++ b/lib/chef/guard_interpreter/resource_guard_interpreter.rb
@@ -88,7 +88,7 @@ class Chef
resource_class = Chef::Resource.resource_for_node(parent_resource.guard_interpreter, parent_resource.node)
if resource_class.nil?
- raise ArgumentError, "Specified guard_interpreter resource #{parent_resource.guard_interpreter.to_s} unknown for this platform"
+ raise ArgumentError, "Specified guard_interpreter resource #{parent_resource.guard_interpreter} unknown for this platform"
end
if ! resource_class.ancestors.include?(Chef::Resource::Execute)
diff --git a/lib/chef/http.rb b/lib/chef/http.rb
index 9f1eeed55f..a26e82f795 100644
--- a/lib/chef/http.rb
+++ b/lib/chef/http.rb
@@ -396,7 +396,7 @@ class Chef
if Chef::Platform.windows?
tf.binmode # required for binary files on Windows platforms
end
- Chef::Log.debug("Streaming download from #{url.to_s} to tempfile #{tf.path}")
+ Chef::Log.debug("Streaming download from #{url} to tempfile #{tf.path}")
# Stolen from http://www.ruby-forum.com/topic/166423
# Kudos to _why!
diff --git a/lib/chef/http/http_request.rb b/lib/chef/http/http_request.rb
index 1baf5724ae..24cd99375d 100644
--- a/lib/chef/http/http_request.rb
+++ b/lib/chef/http/http_request.rb
@@ -127,7 +127,7 @@ class Chef
# http://redmine.ruby-lang.org/issues/show/2758
if e.to_s =~ /#{Regexp.escape(%q|undefined method `closed?' for nil:NilClass|)}/
Chef::Log.debug("Rescued error in http connect, re-raising as Errno::ECONNREFUSED to hide bug in net/http")
- Chef::Log.debug("#{e.class.name}: #{e.to_s}")
+ Chef::Log.debug("#{e.class.name}: #{e}")
Chef::Log.debug(e.backtrace.join("\n"))
raise Errno::ECONNREFUSED, "Connection refused attempting to contact #{url.scheme}://#{host}:#{port}"
else
diff --git a/lib/chef/http/simple.rb b/lib/chef/http/simple.rb
index 8519554f2b..f59fcaa08b 100644
--- a/lib/chef/http/simple.rb
+++ b/lib/chef/http/simple.rb
@@ -1,3 +1,21 @@
+#
+# Author:: Daniel DeLeo (<dan@chef.io>)
+# Copyright:: Copyright (c) 2015 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/http'
require 'chef/http/authenticator'
require 'chef/http/decompressor'
diff --git a/lib/chef/http/simple_json.rb b/lib/chef/http/simple_json.rb
new file mode 100644
index 0000000000..5dfdfbb680
--- /dev/null
+++ b/lib/chef/http/simple_json.rb
@@ -0,0 +1,43 @@
+#
+# Author:: Thom May (<thom@chef.io>)
+# Copyright:: Copyright (c) 2015 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/http'
+require 'chef/http/authenticator'
+require 'chef/http/decompressor'
+require 'chef/http/cookie_manager'
+require 'chef/http/validate_content_length'
+
+class Chef
+ class HTTP
+
+ class SimpleJSON < HTTP
+
+ use JSONInput
+ use JSONOutput
+ use CookieManager
+ use Decompressor
+ use RemoteRequestID
+
+ # ValidateContentLength should come after Decompressor
+ # because the order of middlewares is reversed when handling
+ # responses.
+ use ValidateContentLength
+
+ end
+ end
+end
diff --git a/lib/chef/key.rb b/lib/chef/key.rb
index be4be7f230..47bfe1fcee 100644
--- a/lib/chef/key.rb
+++ b/lib/chef/key.rb
@@ -19,6 +19,7 @@
require 'chef/json_compat'
require 'chef/mixin/params_validate'
require 'chef/exceptions'
+require 'chef/server_api'
class Chef
# Class for interacting with a chef key object. Can be used to create new keys,
@@ -31,7 +32,7 @@ class Chef
# @attr [String] public_key the RSA string of this key
# @attr [String] private_key the RSA string of the private key if returned via a POST or PUT
# @attr [String] expiration_date the ISO formatted string YYYY-MM-DDTHH:MM:SSZ, i.e. 2020-12-24T21:00:00Z
- # @attr [String] rest Chef::REST object, initialized and cached via chef_rest method
+ # @attr [String] rest Chef::ServerAPI object, initialized and cached via chef_rest method
# @attr [string] api_base either "users" or "clients", initialized and cached via api_base method
#
# @attr_reader [String] actor_field_name must be either 'client' or 'user'
@@ -60,9 +61,9 @@ class Chef
def chef_rest
@rest ||= if @actor_field_name == "user"
- Chef::REST.new(Chef::Config[:chef_server_root])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_root])
else
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
end
@@ -151,7 +152,7 @@ class Chef
payload['public_key'] = @public_key unless @public_key.nil?
payload['create_key'] = @create_key if @create_key
payload['expiration_date'] = @expiration_date unless @expiration_date.nil?
- result = chef_rest.post_rest("#{api_base}/#{@actor}/keys", payload)
+ result = chef_rest.post("#{api_base}/#{@actor}/keys", payload)
# append the private key to the current key if the server returned one,
# since the POST endpoint just returns uri and private_key if needed.
new_key = self.to_hash
@@ -174,7 +175,7 @@ class Chef
# to @name.
put_name = @name if put_name.nil?
- new_key = chef_rest.put_rest("#{api_base}/#{@actor}/keys/#{put_name}", to_hash)
+ new_key = chef_rest.put("#{api_base}/#{@actor}/keys/#{put_name}", to_hash)
# if the server returned a public_key, remove the create_key field, as we now have a key
if new_key["public_key"]
self.delete_create_key
@@ -197,7 +198,7 @@ class Chef
raise Chef::Exceptions::MissingKeyAttribute, "the name field must be populated when delete is called"
end
- chef_rest.delete_rest("#{api_base}/#{@actor}/keys/#{@name}")
+ chef_rest.delete("#{api_base}/#{@actor}/keys/#{@name}")
end
# Class methods
@@ -226,22 +227,22 @@ class Chef
end
def self.list_by_user(actor, inflate=false)
- keys = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest("users/#{actor}/keys")
+ keys = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys")
self.list(keys, actor, :load_by_user, inflate)
end
def self.list_by_client(actor, inflate=false)
- keys = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients/#{actor}/keys")
+ keys = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys")
self.list(keys, actor, :load_by_client, inflate)
end
def self.load_by_user(actor, key_name)
- response = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest("users/#{actor}/keys/#{key_name}")
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys/#{key_name}")
Chef::Key.from_hash(response.merge({"user" => actor}))
end
def self.load_by_client(actor, key_name)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients/#{actor}/keys/#{key_name}")
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys/#{key_name}")
Chef::Key.from_hash(response.merge({"client" => actor}))
end
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index 2820f58e85..34e437c82f 100644
--- a/lib/chef/knife.rb
+++ b/lib/chef/knife.rb
@@ -26,14 +26,16 @@ require 'chef/mixin/path_sanity'
require 'chef/knife/core/subcommand_loader'
require 'chef/knife/core/ui'
require 'chef/local_mode'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/http/authenticator'
+require 'chef/http/http_request'
+require 'chef/http'
require 'pp'
class Chef
class Knife
- Chef::REST::RESTRequest.user_agent = "Chef Knife#{Chef::REST::RESTRequest::UA_COMMON}"
+ Chef::HTTP::HTTPRequest.user_agent = "Chef Knife#{Chef::HTTP::HTTPRequest::UA_COMMON}"
include Mixlib::CLI
include Chef::Mixin::PathSanity
@@ -551,15 +553,15 @@ class Chef
def rest
@rest ||= begin
- require 'chef/rest'
- Chef::REST.new(Chef::Config[:chef_server_url])
+ require 'chef/server_api'
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
end
def noauth_rest
@rest ||= begin
- require 'chef/rest'
- Chef::REST.new(Chef::Config[:chef_server_url], false, false)
+ require 'chef/http/simple_json'
+ Chef::HTTP::SimpleJSON.new(Chef::Config[:chef_server_url])
end
end
diff --git a/lib/chef/knife/bootstrap/client_builder.rb b/lib/chef/knife/bootstrap/client_builder.rb
index 6414ac5c72..f5a2ff2bb1 100644
--- a/lib/chef/knife/bootstrap/client_builder.rb
+++ b/lib/chef/knife/bootstrap/client_builder.rb
@@ -17,7 +17,7 @@
#
require 'chef/node'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/api_client/registration'
require 'chef/api_client'
require 'chef/knife/bootstrap'
@@ -185,22 +185,22 @@ class Chef
# @param relative_path [String] URI path relative to the chef organization
# @return [Boolean] if the relative path exists or returns a 404
def resource_exists?(relative_path)
- rest.get_rest(relative_path)
+ rest.get(relative_path)
true
rescue Net::HTTPServerException => e
raise unless e.response.code == "404"
false
end
- # @return [Chef::REST] REST client using the client credentials
+ # @return [Chef::ServerAPI] REST client using the client credentials
def client_rest
- @client_rest ||= Chef::REST.new(chef_server_url, node_name, client_path)
+ @client_rest ||= Chef::ServerAPI.new(chef_server_url, :client_name => node_name, :signing_key_filename => client_path)
end
- # @return [Chef::REST] REST client using the cli user's knife credentials
+ # @return [Chef::ServerAPI] REST client using the cli user's knife credentials
# this uses the users's credentials
def rest
- @rest ||= Chef::REST.new(chef_server_url)
+ @rest ||= Chef::ServerAPI.new(chef_server_url)
end
end
end
diff --git a/lib/chef/knife/cookbook_bulk_delete.rb b/lib/chef/knife/cookbook_bulk_delete.rb
index 65fa888486..ec0d06937f 100644
--- a/lib/chef/knife/cookbook_bulk_delete.rb
+++ b/lib/chef/knife/cookbook_bulk_delete.rb
@@ -60,9 +60,9 @@ class Chef
cookbooks_names.each do |cookbook_name|
- versions = rest.get_rest("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map {|v| v["version"]}.flatten
+ versions = rest.get("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map {|v| v["version"]}.flatten
versions.each do |version|
- object = rest.delete_rest("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}")
+ object = rest.delete("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}")
ui.info("Deleted cookbook #{cookbook_name.ljust(25)} [#{version}]")
end
end
diff --git a/lib/chef/knife/cookbook_delete.rb b/lib/chef/knife/cookbook_delete.rb
index f436d270bd..5fe0e9664d 100644
--- a/lib/chef/knife/cookbook_delete.rb
+++ b/lib/chef/knife/cookbook_delete.rb
@@ -85,7 +85,7 @@ class Chef
end
def available_versions
- @available_versions ||= rest.get_rest("cookbooks/#{@cookbook_name}").map do |name, url_and_version|
+ @available_versions ||= rest.get("cookbooks/#{@cookbook_name}").map do |name, url_and_version|
url_and_version["versions"].map {|url_by_version| url_by_version["version"]}
end.flatten
rescue Net::HTTPServerException => e
@@ -143,7 +143,7 @@ class Chef
def delete_request(path)
path += "?purge=true" if config[:purge]
- rest.delete_rest(path)
+ rest.delete(path)
end
end
diff --git a/lib/chef/knife/cookbook_download.rb b/lib/chef/knife/cookbook_download.rb
index cb8eeb8edf..6ba5fc7d6c 100644
--- a/lib/chef/knife/cookbook_download.rb
+++ b/lib/chef/knife/cookbook_download.rb
@@ -69,7 +69,7 @@ class Chef
ui.info("Downloading #{@cookbook_name} cookbook version #{@version}")
- cookbook = rest.get_rest("cookbooks/#{@cookbook_name}/#{@version}")
+ cookbook = Chef::CookbookVersion.load(@cookbook_name, @version)
manifest = cookbook.manifest
basedir = File.join(config[:download_directory], "#{@cookbook_name}-#{cookbook.version}")
@@ -90,8 +90,7 @@ class Chef
dest = File.join(basedir, segment_file['path'].gsub('/', File::SEPARATOR))
Chef::Log.debug("Downloading #{segment_file['path']} to #{dest}")
FileUtils.mkdir_p(File.dirname(dest))
- rest.sign_on_redirect = false
- tempfile = rest.get_rest(segment_file['url'], true)
+ tempfile = rest.streaming_request(segment_file['url'])
FileUtils.mv(tempfile.path, dest)
end
end
diff --git a/lib/chef/knife/cookbook_list.rb b/lib/chef/knife/cookbook_list.rb
index 75f18a154b..dd78e854da 100644
--- a/lib/chef/knife/cookbook_list.rb
+++ b/lib/chef/knife/cookbook_list.rb
@@ -39,7 +39,7 @@ class Chef
env = config[:environment]
num_versions = config[:all_versions] ? "num_versions=all" : "num_versions=1"
api_endpoint = env ? "/environments/#{env}/cookbooks?#{num_versions}" : "/cookbooks?#{num_versions}"
- cookbook_versions = rest.get_rest(api_endpoint)
+ cookbook_versions = rest.get(api_endpoint)
ui.output(format_cookbook_list_for_display(cookbook_versions))
end
end
diff --git a/lib/chef/knife/cookbook_show.rb b/lib/chef/knife/cookbook_show.rb
index 7c9cbebdb1..07f7684c27 100644
--- a/lib/chef/knife/cookbook_show.rb
+++ b/lib/chef/knife/cookbook_show.rb
@@ -67,9 +67,9 @@ class Chef
cookbook_name, segment, filename = @name_args[0], @name_args[2], @name_args[3]
cookbook_version = @name_args[1] == 'latest' ? '_latest' : @name_args[1]
- cookbook = rest.get_rest("cookbooks/#{cookbook_name}/#{cookbook_version}")
+ cookbook = rest.get("cookbooks/#{cookbook_name}/#{cookbook_version}")
manifest_entry = cookbook.preferred_manifest_record(node, segment, filename)
- temp_file = rest.get_rest(manifest_entry[:url], true)
+ temp_file = rest.get(manifest_entry[:url], true)
# the temp file is cleaned up elsewhere
temp_file.open if temp_file.closed?
@@ -77,16 +77,16 @@ class Chef
when 3 # We are showing a specific part of the cookbook
cookbook_version = @name_args[1] == 'latest' ? '_latest' : @name_args[1]
- result = rest.get_rest("cookbooks/#{@name_args[0]}/#{cookbook_version}")
+ result = rest.get("cookbooks/#{@name_args[0]}/#{cookbook_version}")
output(result.manifest[@name_args[2]])
when 2 # We are showing the whole cookbook data
cookbook_version = @name_args[1] == 'latest' ? '_latest' : @name_args[1]
- output(rest.get_rest("cookbooks/#{@name_args[0]}/#{cookbook_version}"))
+ output(rest.get("cookbooks/#{@name_args[0]}/#{cookbook_version}"))
when 1 # We are showing the cookbook versions (all of them)
cookbook_name = @name_args[0]
env = config[:environment]
api_endpoint = env ? "environments/#{env}/cookbooks/#{cookbook_name}" : "cookbooks/#{cookbook_name}"
- output(format_cookbook_list_for_display(rest.get_rest(api_endpoint)))
+ output(format_cookbook_list_for_display(rest.get(api_endpoint)))
when 0
show_usage
ui.fatal("You must specify a cookbook name")
diff --git a/lib/chef/knife/cookbook_site_download.rb b/lib/chef/knife/cookbook_site_download.rb
index 3e586e6542..72608f3a30 100644
--- a/lib/chef/knife/cookbook_site_download.rb
+++ b/lib/chef/knife/cookbook_site_download.rb
@@ -63,7 +63,7 @@ class Chef
def current_cookbook_data
@current_cookbook_data ||= begin
- noauth_rest.get_rest "#{cookbooks_api_url}/#{@name_args[0]}"
+ noauth_rest.get "#{cookbooks_api_url}/#{@name_args[0]}"
end
end
@@ -79,14 +79,14 @@ class Chef
specific_cookbook_version_url
end
- noauth_rest.get_rest uri
+ noauth_rest.get uri
end
end
def download_cookbook
ui.info "Downloading #{@name_args[0]} from Supermarket at version #{version} to #{download_location}"
noauth_rest.sign_on_redirect = false
- tf = noauth_rest.get_rest desired_cookbook_data["file"], true
+ tf = noauth_rest.get desired_cookbook_data["file"], true
::FileUtils.cp tf.path, download_location
ui.info "Cookbook saved: #{download_location}"
diff --git a/lib/chef/knife/cookbook_site_list.rb b/lib/chef/knife/cookbook_site_list.rb
index 846123c867..b5354ed6e6 100644
--- a/lib/chef/knife/cookbook_site_list.rb
+++ b/lib/chef/knife/cookbook_site_list.rb
@@ -42,7 +42,7 @@ class Chef
def get_cookbook_list(items=10, start=0, cookbook_collection={})
cookbooks_url = "https://supermarket.chef.io/api/v1/cookbooks?items=#{items}&start=#{start}"
- cr = noauth_rest.get_rest(cookbooks_url)
+ cr = noauth_rest.get(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
end
diff --git a/lib/chef/knife/cookbook_site_search.rb b/lib/chef/knife/cookbook_site_search.rb
index 0baaf90f1c..decbf6c2c3 100644
--- a/lib/chef/knife/cookbook_site_search.rb
+++ b/lib/chef/knife/cookbook_site_search.rb
@@ -30,7 +30,7 @@ class Chef
def search_cookbook(query, items=10, start=0, cookbook_collection={})
cookbooks_url = "https://supermarket.chef.io/api/v1/search?q=#{query}&items=#{items}&start=#{start}"
- cr = noauth_rest.get_rest(cookbooks_url)
+ cr = noauth_rest.get(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
end
diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb
index beb98b71b8..043ca84a58 100644
--- a/lib/chef/knife/cookbook_site_share.rb
+++ b/lib/chef/knife/cookbook_site_share.rb
@@ -108,7 +108,7 @@ class Chef
def get_category(cookbook_name)
begin
- data = noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}")
+ data = noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}")
if !data["category"] && data["error_code"]
ui.fatal("Received an error from Supermarket: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.")
exit(1)
diff --git a/lib/chef/knife/cookbook_site_show.rb b/lib/chef/knife/cookbook_site_show.rb
index 6b65b62570..521a60eb36 100644
--- a/lib/chef/knife/cookbook_site_show.rb
+++ b/lib/chef/knife/cookbook_site_show.rb
@@ -31,15 +31,15 @@ class Chef
def get_cookbook_data
case @name_args.length
when 1
- noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}")
+ noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}")
when 2
- noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
+ noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
end
end
def get_cookbook_list(items=10, start=0, cookbook_collection={})
cookbooks_url = "https://supermarket.chef.io/api/v1/cookbooks?items=#{items}&start=#{start}"
- cr = noauth_rest.get_rest(cookbooks_url)
+ cr = noauth_rest.get(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
end
diff --git a/lib/chef/knife/cookbook_site_unshare.rb b/lib/chef/knife/cookbook_site_unshare.rb
index 77bb18322c..0c196c328a 100644
--- a/lib/chef/knife/cookbook_site_unshare.rb
+++ b/lib/chef/knife/cookbook_site_unshare.rb
@@ -41,7 +41,7 @@ class Chef
confirm "Do you really want to unshare all versions of the cookbook #{@cookbook_name}"
begin
- rest.delete_rest "https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}"
+ rest.delete "https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}"
rescue Net::HTTPServerException => e
raise e unless e.message =~ /Forbidden/
ui.error "Forbidden: You must be the maintainer of #{@cookbook_name} to unshare it."
diff --git a/lib/chef/knife/data_bag_create.rb b/lib/chef/knife/data_bag_create.rb
index f8a7619a8a..1becad88b9 100644
--- a/lib/chef/knife/data_bag_create.rb
+++ b/lib/chef/knife/data_bag_create.rb
@@ -51,7 +51,7 @@ class Chef
# create the data bag
begin
- rest.post_rest("data", { "name" => @data_bag_name })
+ rest.post("data", { "name" => @data_bag_name })
ui.info("Created data_bag[#{@data_bag_name}]")
rescue Net::HTTPServerException => e
raise unless e.to_s =~ /^409/
@@ -68,7 +68,7 @@ class Chef
output
end)
item.data_bag(@data_bag_name)
- rest.post_rest("data/#{@data_bag_name}", item)
+ rest.post("data/#{@data_bag_name}", item)
end
end
end
diff --git a/lib/chef/knife/data_bag_delete.rb b/lib/chef/knife/data_bag_delete.rb
index 575e9d604d..a3215d4c54 100644
--- a/lib/chef/knife/data_bag_delete.rb
+++ b/lib/chef/knife/data_bag_delete.rb
@@ -32,11 +32,11 @@ class Chef
def run
if @name_args.length == 2
delete_object(Chef::DataBagItem, @name_args[1], "data_bag_item") do
- rest.delete_rest("data/#{@name_args[0]}/#{@name_args[1]}")
+ rest.delete("data/#{@name_args[0]}/#{@name_args[1]}")
end
elsif @name_args.length == 1
delete_object(Chef::DataBag, @name_args[0], "data_bag") do
- rest.delete_rest("data/#{@name_args[0]}")
+ rest.delete("data/#{@name_args[0]}")
end
else
show_usage
diff --git a/lib/chef/knife/data_bag_edit.rb b/lib/chef/knife/data_bag_edit.rb
index 6ef4b33f59..88c5669508 100644
--- a/lib/chef/knife/data_bag_edit.rb
+++ b/lib/chef/knife/data_bag_edit.rb
@@ -65,7 +65,7 @@ class Chef
item_to_save = edited_item
end
- rest.put_rest("data/#{@name_args[0]}/#{@name_args[1]}", item_to_save)
+ rest.put("data/#{@name_args[0]}/#{@name_args[1]}", item_to_save)
stdout.puts("Saved data_bag_item[#{@name_args[1]}]")
ui.output(edited_item) if config[:print_after]
end
diff --git a/lib/chef/knife/environment_compare.rb b/lib/chef/knife/environment_compare.rb
index 792ec444ea..54f011f323 100644
--- a/lib/chef/knife/environment_compare.rb
+++ b/lib/chef/knife/environment_compare.rb
@@ -57,7 +57,7 @@ class Chef
end
# Get all cookbooks so we can compare them all
- cookbooks = rest.get_rest("/cookbooks?num_versions=1") if config[:all]
+ cookbooks = rest.get("/cookbooks?num_versions=1") if config[:all]
# display matrix view of in the requested format.
if config[:format] == 'summary'
diff --git a/lib/chef/knife/index_rebuild.rb b/lib/chef/knife/index_rebuild.rb
index 4b9fcdd159..95b0dcaffb 100644
--- a/lib/chef/knife/index_rebuild.rb
+++ b/lib/chef/knife/index_rebuild.rb
@@ -38,7 +38,7 @@ class Chef
else
deprecated_server_message
nag
- output rest.post_rest("/search/reindex", {})
+ output rest.post("/search/reindex", {})
end
end
@@ -50,7 +50,7 @@ class Chef
# for a node we know won't exist; the 404 response that comes
# back will give us what we want
dummy_node = "knife_index_rebuild_test_#{rand(1000000)}"
- rest.get_rest("/nodes/#{dummy_node}")
+ rest.get("/nodes/#{dummy_node}")
rescue Net::HTTPServerException => exception
r = exception.response
parse_api_info(r)
diff --git a/lib/chef/knife/raw.rb b/lib/chef/knife/raw.rb
index 601cfcef9b..de8742deb9 100644
--- a/lib/chef/knife/raw.rb
+++ b/lib/chef/knife/raw.rb
@@ -1,4 +1,5 @@
require 'chef/knife'
+require 'chef/http'
class Chef
class Knife
diff --git a/lib/chef/knife/recipe_list.rb b/lib/chef/knife/recipe_list.rb
index ed7d2a9509..46ad619f1d 100644
--- a/lib/chef/knife/recipe_list.rb
+++ b/lib/chef/knife/recipe_list.rb
@@ -22,7 +22,7 @@ class Chef::Knife::RecipeList < Chef::Knife
banner "knife recipe list [PATTERN]"
def run
- recipes = rest.get_rest('cookbooks/_recipes')
+ recipes = rest.get('cookbooks/_recipes')
if pattern = @name_args.first
recipes = recipes.grep(Regexp.new(pattern))
end
diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb
index 1a61b035cb..e649c01ef4 100644
--- a/lib/chef/knife/status.rb
+++ b/lib/chef/knife/status.rb
@@ -76,7 +76,7 @@ class Chef
time = Time.now.to_i
# AND NOT is not valid lucene syntax, so don't use append_to_query
@query << " " unless @query.empty?
- @query << "NOT ohai_time:[#{(time - 60*60).to_s} TO #{time.to_s}]"
+ @query << "NOT ohai_time:[#{(time - 60*60)} TO #{time}]"
end
if config[:hide_by_mins]
@@ -84,7 +84,7 @@ class Chef
time = Time.now.to_i
# AND NOT is not valid lucene syntax, so don't use append_to_query
@query << " " unless @query.empty?
- @query << "NOT ohai_time:[#{(time - hidemins*60).to_s} TO #{time.to_s}]"
+ @query << "NOT ohai_time:[#{(time - hidemins*60)} TO #{time}]"
end
@query = @query.empty? ? "*:*" : @query
diff --git a/lib/chef/mixin/securable.rb b/lib/chef/mixin/securable.rb
index aaedf0b9ba..396243693e 100644
--- a/lib/chef/mixin/securable.rb
+++ b/lib/chef/mixin/securable.rb
@@ -112,7 +112,7 @@ class Chef
# equivalent to something like:
# def rights(permissions=nil, principals=nil, args_hash=nil)
define_method(name) do |permissions=nil, principals=nil, args_hash=nil|
- rights = self.instance_variable_get("@#{name.to_s}".to_sym)
+ rights = self.instance_variable_get("@#{name}".to_sym)
unless permissions.nil?
input = {
:permissions => permissions,
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 0c13e5474a..f6c7d68f74 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -27,7 +27,7 @@ require 'chef/mixin/deep_merge'
require 'chef/dsl/include_attribute'
require 'chef/dsl/platform_introspection'
require 'chef/environment'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/run_list'
require 'chef/node/attribute'
require 'chef/mash'
@@ -99,10 +99,10 @@ class Chef
# for saving node data we use validate_utf8: false which will not
# raise an exception on bad utf8 data, but will replace the bad
# characters and render valid JSON.
- @chef_server_rest ||= Chef::REST.new(
+ @chef_server_rest ||= Chef::ServerAPI.new(
Chef::Config[:chef_server_url],
- Chef::Config[:node_name],
- Chef::Config[:client_key],
+ client_name: Chef::Config[:node_name],
+ signing_key_filename: Chef::Config[:client_key],
validate_utf8: false,
)
end
@@ -390,7 +390,7 @@ class Chef
if attrs.key?("recipes") || attrs.key?("run_list")
raise Chef::Exceptions::AmbiguousRunlistSpecification, "please set the node's run list using the 'run_list' attribute only."
end
- Chef::Log.info("Setting the run_list to #{new_run_list.to_s} from CLI options")
+ Chef::Log.info("Setting the run_list to #{new_run_list} from CLI options")
run_list(new_run_list)
end
attrs
@@ -532,6 +532,11 @@ class Chef
# Create a Chef::Node from JSON
def self.json_create(o)
+ from_hash(o)
+ end
+
+ def self.from_hash(o)
+ return o if o.kind_of? Chef::Node
node = new
node.name(o["name"])
node.chef_environment(o["chef_environment"])
@@ -561,7 +566,7 @@ class Chef
Chef::Search::Query.new.search(:node, "chef_environment:#{environment}") {|n| response[n.name] = n unless n.nil?}
response
else
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("environments/#{environment}/nodes")
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("environments/#{environment}/nodes")
end
end
@@ -569,11 +574,12 @@ class Chef
if inflate
response = Hash.new
Chef::Search::Query.new.search(:node) do |n|
+ n = Chef::Node.from_hash(n)
response[n.name] = n unless n.nil?
end
response
else
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("nodes")
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("nodes")
end
end
@@ -594,12 +600,12 @@ class Chef
# Load a node by name
def self.load(name)
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("nodes/#{name}")
+ from_hash(Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("nodes/#{name}"))
end
# Remove this node via the REST API
def destroy
- chef_server_rest.delete_rest("nodes/#{name}")
+ chef_server_rest.delete("nodes/#{name}")
end
# Save this node via the REST API
@@ -610,11 +616,11 @@ class Chef
if Chef::Config[:why_run]
Chef::Log.warn("In why-run mode, so NOT performing node save.")
else
- chef_server_rest.put_rest("nodes/#{name}", data_for_save)
+ chef_server_rest.put("nodes/#{name}", data_for_save)
end
rescue Net::HTTPServerException => e
if e.response.code == "404"
- chef_server_rest.post_rest("nodes", data_for_save)
+ chef_server_rest.post("nodes", data_for_save)
# Chef Server before 12.3 rejects node JSON with 'policy_name' or
# 'policy_group' keys, but 'policy_name' will be detected first.
# Backcompat can be removed in 13.0
@@ -629,14 +635,14 @@ class Chef
# Create the node via the REST API
def create
- chef_server_rest.post_rest("nodes", data_for_save)
+ chef_server_rest.post("nodes", data_for_save)
self
rescue Net::HTTPServerException => e
# Chef Server before 12.3 rejects node JSON with 'policy_name' or
# 'policy_group' keys, but 'policy_name' will be detected first.
# Backcompat can be removed in 13.0
if e.response.code == "400" && e.response.body.include?("Invalid key policy_name")
- chef_server_rest.post_rest("nodes", data_for_save_without_policyfile_attrs)
+ chef_server_rest.post("nodes", data_for_save_without_policyfile_attrs)
else
raise
end
@@ -663,10 +669,10 @@ class Chef
def save_without_policyfile_attrs
trimmed_data = data_for_save_without_policyfile_attrs
- chef_server_rest.put_rest("nodes/#{name}", trimmed_data)
+ chef_server_rest.put("nodes/#{name}", trimmed_data)
rescue Net::HTTPServerException => e
raise e unless e.response.code == "404"
- chef_server_rest.post_rest("nodes", trimmed_data)
+ chef_server_rest.post("nodes", trimmed_data)
end
def data_for_save_without_policyfile_attrs
diff --git a/lib/chef/org.rb b/lib/chef/org.rb
index 41d74b6186..81eca6a991 100644
--- a/lib/chef/org.rb
+++ b/lib/chef/org.rb
@@ -18,7 +18,7 @@
require 'chef/json_compat'
require 'chef/mixin/params_validate'
-require 'chef/rest'
+require 'chef/server_api'
class Chef
class Org
@@ -35,7 +35,7 @@ class Chef
end
def chef_rest
- @chef_rest ||= Chef::REST.new(Chef::Config[:chef_server_root])
+ @chef_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_root])
end
def name(arg=nil)
@@ -74,18 +74,18 @@ class Chef
def create
payload = {:name => self.name, :full_name => self.full_name}
- new_org = chef_rest.post_rest("organizations", payload)
+ new_org = chef_rest.post("organizations", payload)
Chef::Org.from_hash(self.to_hash.merge(new_org))
end
def update
payload = {:name => self.name, :full_name => self.full_name}
- new_org = chef_rest.put_rest("organizations/#{name}", payload)
+ new_org = chef_rest.put("organizations/#{name}", payload)
Chef::Org.from_hash(self.to_hash.merge(new_org))
end
def destroy
- chef_rest.delete_rest("organizations/#{@name}")
+ chef_rest.delete("organizations/#{@name}")
end
def save
@@ -102,13 +102,13 @@ class Chef
def associate_user(username)
request_body = {:user => username}
- response = chef_rest.post_rest "organizations/#{@name}/association_requests", request_body
+ response = chef_rest.post "organizations/#{@name}/association_requests", request_body
association_id = response["uri"].split("/").last
- chef_rest.put_rest "users/#{username}/association_requests/#{association_id}", { :response => 'accept' }
+ chef_rest.put "users/#{username}/association_requests/#{association_id}", { :response => 'accept' }
end
def dissociate_user(username)
- chef_rest.delete_rest "organizations/#{name}/users/#{username}"
+ chef_rest.delete "organizations/#{name}/users/#{username}"
end
# Class methods
@@ -129,12 +129,12 @@ class Chef
end
def self.load(org_name)
- response = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest("organizations/#{org_name}")
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("organizations/#{org_name}")
Chef::Org.from_hash(response)
end
def self.list(inflate=false)
- orgs = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest('organizations')
+ orgs = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get('organizations')
if inflate
orgs.inject({}) do |org_map, (name, _url)|
org_map[name] = Chef::Org.load(name)
diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb
index 9b511f0237..1de6d61029 100644
--- a/lib/chef/platform/provider_mapping.rb
+++ b/lib/chef/platform/provider_mapping.rb
@@ -53,7 +53,7 @@ class Chef
begin
version_constraint = Chef::VersionConstraint::Platform.new(platform_version)
if version_constraint.include?(version)
- Chef::Log.debug("Platform #{name.to_s} version #{version} found")
+ Chef::Log.debug("Platform #{name} version #{version} found")
provider_map.merge!(provider)
end
rescue Chef::Exceptions::InvalidPlatformVersion
diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb
index c9842ba532..d4b3df748e 100644
--- a/lib/chef/policy_builder/dynamic.rb
+++ b/lib/chef/policy_builder/dynamic.rb
@@ -19,7 +19,6 @@
require 'forwardable'
require 'chef/log'
-require 'chef/rest'
require 'chef/run_context'
require 'chef/config'
require 'chef/node'
diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb
index 848dd00684..870351b6fb 100644
--- a/lib/chef/policy_builder/expand_node_object.rb
+++ b/lib/chef/policy_builder/expand_node_object.rb
@@ -20,7 +20,7 @@
#
require 'chef/log'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/run_context'
require 'chef/config'
require 'chef/node'
@@ -198,7 +198,12 @@ class Chef
begin
events.cookbook_resolution_start(@expanded_run_list_with_versions)
cookbook_hash = api_service.post("environments/#{node.chef_environment}/cookbook_versions",
- {:run_list => @expanded_run_list_with_versions})
+ {:run_list => @expanded_run_list_with_versions})
+
+ cookbook_hash = cookbook_hash.inject({}) do |memo, (key, value)|
+ memo[key] = Chef::CookbookVersion.from_hash(value)
+ memo
+ end
rescue Exception => e
# TODO: wrap/munge exception to provide helpful error output
events.cookbook_resolution_failed(@expanded_run_list_with_versions, e)
@@ -257,7 +262,7 @@ class Chef
end
def api_service
- @api_service ||= Chef::REST.new(config[:chef_server_url])
+ @api_service ||= Chef::ServerAPI.new(config[:chef_server_url])
end
def config
diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb
index 3633110d6c..249bebbd98 100644
--- a/lib/chef/policy_builder/policyfile.rb
+++ b/lib/chef/policy_builder/policyfile.rb
@@ -20,10 +20,10 @@
#
require 'chef/log'
-require 'chef/rest'
require 'chef/run_context'
require 'chef/config'
require 'chef/node'
+require 'chef/server_api'
class Chef
module PolicyBuilder
@@ -455,7 +455,7 @@ class Chef
# @api private
def http_api
- @api_service ||= Chef::REST.new(config[:chef_server_url])
+ @api_service ||= Chef::ServerAPI.new(config[:chef_server_url])
end
# @api private
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb
index 68bc8d78bd..c53f4a6991 100644
--- a/lib/chef/provider.rb
+++ b/lib/chef/provider.rb
@@ -94,7 +94,7 @@ class Chef
end
def load_current_resource
- raise Chef::Exceptions::Override, "You must override load_current_resource in #{self.to_s}"
+ raise Chef::Exceptions::Override, "You must override load_current_resource in #{self}"
end
def define_resource_requirements
@@ -104,7 +104,7 @@ class Chef
end
def action_nothing
- Chef::Log.debug("Doing nothing for #{@new_resource.to_s}")
+ Chef::Log.debug("Doing nothing for #{@new_resource}")
true
end
@@ -209,7 +209,7 @@ class Chef
else
specified_properties.map { |p| "#{p}=#{new_resource.send(p).inspect}" }.join(", ")
end
- Chef::Log.debug("Skipping update of #{new_resource.to_s}: has not changed any of the specified properties #{properties_str}.")
+ Chef::Log.debug("Skipping update of #{new_resource}: has not changed any of the specified properties #{properties_str}.")
return false
end
diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb
index c59200e717..fe6b288eda 100644
--- a/lib/chef/provider/deploy.rb
+++ b/lib/chef/provider/deploy.rb
@@ -365,7 +365,7 @@ class Chef
end
def release_slug
- raise Chef::Exceptions::Override, "You must override release_slug in #{self.to_s}"
+ raise Chef::Exceptions::Override, "You must override release_slug in #{self}"
end
def install_gems
diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb
index fd25a14ea5..432fe3987f 100644
--- a/lib/chef/provider/dsc_resource.rb
+++ b/lib/chef/provider/dsc_resource.rb
@@ -144,7 +144,7 @@ class Chef
def invoke_resource(method, output_format=:object)
properties = translate_type(@new_resource.properties)
- switches = "-Method #{method.to_s} -Name #{@new_resource.resource}"\
+ switches = "-Method #{method} -Name #{@new_resource.resource}"\
" -Property #{properties} -Verbose"
if module_name != :none
switches += " -Module #{module_name}"
diff --git a/lib/chef/provider/dsc_script.rb b/lib/chef/provider/dsc_script.rb
index b2432132b7..8205910d5a 100644
--- a/lib/chef/provider/dsc_script.rb
+++ b/lib/chef/provider/dsc_script.rb
@@ -99,7 +99,7 @@ class Chef
configuration_document = generate_configuration_document(config_directory, configuration_flags)
@operations[operation].call(config_manager, configuration_document, shellout_flags)
rescue Exception => e
- Chef::Log.error("DSC operation failed: #{e.message.to_s}")
+ Chef::Log.error("DSC operation failed: #{e.message}")
raise e
ensure
::FileUtils.rm_rf(config_directory)
diff --git a/lib/chef/provider/env.rb b/lib/chef/provider/env.rb
index cf75ff7d85..8bd7b3e6ca 100644
--- a/lib/chef/provider/env.rb
+++ b/lib/chef/provider/env.rb
@@ -48,7 +48,7 @@ class Chef
end
def env_value(key_name)
- raise Chef::Exceptions::Env, "#{self.to_s} provider does not implement env_value!"
+ raise Chef::Exceptions::Env, "#{self} provider does not implement env_value!"
end
def env_key_exists(key_name)
@@ -141,11 +141,11 @@ class Chef
end
def create_env
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :#{@new_resource.action}"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :#{@new_resource.action}"
end
def delete_env
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :delete"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :delete"
end
def modify_env
diff --git a/lib/chef/provider/group/aix.rb b/lib/chef/provider/group/aix.rb
index 92bb8cb225..d0de538e58 100644
--- a/lib/chef/provider/group/aix.rb
+++ b/lib/chef/provider/group/aix.rb
@@ -72,7 +72,7 @@ class Chef
{ :gid => "id" }.sort { |a,b| a[0] <=> b[0] }.each do |field, option|
if @current_resource.send(field) != @new_resource.send(field)
if @new_resource.send(field)
- Chef::Log.debug("#{@new_resource} setting #{field.to_s} to #{@new_resource.send(field)}")
+ Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field)}")
opts << " '#{option}=#{@new_resource.send(field)}'"
end
end
diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb
index cb480aab54..b2ca8fd4fe 100644
--- a/lib/chef/provider/group/groupadd.rb
+++ b/lib/chef/provider/group/groupadd.rb
@@ -96,15 +96,15 @@ class Chef
end
def add_member(member)
- raise Chef::Exceptions::Group, "you must override add_member in #{self.to_s}"
+ raise Chef::Exceptions::Group, "you must override add_member in #{self}"
end
def remove_member(member)
- raise Chef::Exceptions::Group, "you must override remove_member in #{self.to_s}"
+ raise Chef::Exceptions::Group, "you must override remove_member in #{self}"
end
def set_members(members)
- raise Chef::Exceptions::Group, "you must override set_members in #{self.to_s}"
+ raise Chef::Exceptions::Group, "you must override set_members in #{self}"
end
# Little bit of magic as per Adam's useradd provider to pull the assign the command line flags
@@ -117,7 +117,7 @@ class Chef
if @current_resource.send(field) != @new_resource.send(field)
if @new_resource.send(field)
opts << " #{option} '#{@new_resource.send(field)}'"
- Chef::Log.debug("#{@new_resource} set #{field.to_s} to #{@new_resource.send(field)}")
+ Chef::Log.debug("#{@new_resource} set #{field} to #{@new_resource.send(field)}")
end
end
end
diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb
index d78d42d6e1..e3d960280d 100644
--- a/lib/chef/provider/group/usermod.rb
+++ b/lib/chef/provider/group/usermod.rb
@@ -41,13 +41,13 @@ class Chef
requirements.assert(:modify, :manage) do |a|
a.assertion { @new_resource.members.empty? || @new_resource.append }
- a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self.to_s}, must set append true in group"
+ a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self}, must set append true in group"
# No whyrun alternative - this action is simply not supported.
end
requirements.assert(:all_actions) do |a|
a.assertion { @new_resource.excluded_members.empty? }
- a.failure_message Chef::Exceptions::Group, "excluded_members is not supported by #{self.to_s}"
+ a.failure_message Chef::Exceptions::Group, "excluded_members is not supported by #{self}"
# No whyrun alternative - this action is simply not supported.
end
end
@@ -62,7 +62,7 @@ class Chef
add_member(member)
end
else
- raise Chef::Exceptions::UnsupportedAction, "Setting members directly is not supported by #{self.to_s}"
+ raise Chef::Exceptions::UnsupportedAction, "Setting members directly is not supported by #{self}"
end
end
@@ -73,7 +73,7 @@ class Chef
def remove_member(member)
# This provider only supports adding members with
# append. This function should never be called.
- raise Chef::Exceptions::UnsupportedAction, "Removing members members is not supported by #{self.to_s}"
+ raise Chef::Exceptions::UnsupportedAction, "Removing members members is not supported by #{self}"
end
def append_flags
diff --git a/lib/chef/provider/link.rb b/lib/chef/provider/link.rb
index c811c13cdf..a5f9b0bb29 100644
--- a/lib/chef/provider/link.rb
+++ b/lib/chef/provider/link.rb
@@ -80,7 +80,7 @@ class Chef
true
end
end
- a.failure_message Chef::Exceptions::Link, "Cannot delete #{@new_resource} at #{@new_resource.target_file}! Not a #{@new_resource.link_type.to_s} link."
+ a.failure_message Chef::Exceptions::Link, "Cannot delete #{@new_resource} at #{@new_resource.target_file}! Not a #{@new_resource.link_type} link."
a.whyrun("Would assume the link at #{@new_resource.target_file} was previously created")
end
end
diff --git a/lib/chef/provider/mount.rb b/lib/chef/provider/mount.rb
index 6bdfd5b867..dc0382c689 100644
--- a/lib/chef/provider/mount.rb
+++ b/lib/chef/provider/mount.rb
@@ -118,12 +118,12 @@ class Chef
# should actually check if the filesystem is mounted (not just return current_resource) and return true/false
def mounted?
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not implement #mounted?"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not implement #mounted?"
end
# should check new_resource against current_resource to see if mount options need updating, returns true/false
def mount_options_unchanged?
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not implement #mount_options_unchanged?"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not implement #mount_options_unchanged?"
end
#
@@ -134,28 +134,28 @@ class Chef
# should implement mounting of the filesystem, raises if action does not succeed
def mount_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :mount"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :mount"
end
# should implement unmounting of the filesystem, raises if action does not succeed
def umount_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :umount"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :umount"
end
# should implement remounting of the filesystem (via a -o remount or some other atomic-ish action that isn't
# simply a umount/mount style remount), raises if action does not succeed
def remount_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remount"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :remount"
end
# should implement enabling of the filesystem (e.g. in /etc/fstab), raises if action does not succeed
def enable_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :enable"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :enable"
end
# should implement disabling of the filesystem (e.g. in /etc/fstab), raises if action does not succeed
def disable_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :disable"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :disable"
end
private
diff --git a/lib/chef/provider/osx_profile.rb b/lib/chef/provider/osx_profile.rb
index ee355fd38e..085397efea 100644
--- a/lib/chef/provider/osx_profile.rb
+++ b/lib/chef/provider/osx_profile.rb
@@ -121,7 +121,7 @@ class Chef
# file must exist in cookbook
if new_profile.end_with?('.mobileconfig')
unless cookbook_file_available?(new_profile)
- error_string = "#{self.to_s}: '#{new_profile}' not found in cookbook"
+ error_string = "#{self}: '#{new_profile}' not found in cookbook"
raise Chef::Exceptions::FileNotFound, error_string
end
cookbook_profile = cache_cookbook_profile(new_profile)
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 8e98a103bf..2238dc8654 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -228,27 +228,27 @@ class Chef
end
def install_package(name, version)
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :install"
end
def upgrade_package(name, version)
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :upgrade"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :upgrade"
end
def remove_package(name, version)
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :remove"
end
def purge_package(name, version)
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :purge"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :purge"
end
def preseed_package(file)
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support pre-seeding package install/upgrade instructions"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support pre-seeding package install/upgrade instructions"
end
def reconfig_package(name, version)
- raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" )
+ raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :reconfig" )
end
# used by subclasses. deprecated. use #a_to_s instead.
diff --git a/lib/chef/provider/package/chocolatey.rb b/lib/chef/provider/package/chocolatey.rb
new file mode 100644
index 0000000000..7a9173e077
--- /dev/null
+++ b/lib/chef/provider/package/chocolatey.rb
@@ -0,0 +1,246 @@
+#
+# Copyright:: Copyright (c) 2015 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/provider/package'
+require 'chef/resource/chocolatey_package'
+require 'chef/mixin/powershell_out'
+
+class Chef
+ class Provider
+ class Package
+ class Chocolatey < Chef::Provider::Package
+ include Chef::Mixin::PowershellOut
+
+ provides :chocolatey_package, os: "windows"
+
+ # Declare that our arguments should be arrays
+ use_multipackage_api
+
+ # Responsible for building the current_resource.
+ #
+ # @return [Chef::Resource::ChocolateyPackage] the current_resource
+ def load_current_resource
+ @current_resource = Chef::Resource::ChocolateyPackage.new(new_resource.name)
+ current_resource.package_name(new_resource.package_name)
+ current_resource.version(build_current_versions)
+ current_resource
+ end
+
+ def define_resource_requirements
+ super
+
+ # Chocolatey source attribute points to an alternate feed
+ # and not a package specific alternate source like other providers
+ # so we want to assert candidates exist for the alternate source
+ requirements.assert(:upgrade, :install) do |a|
+ a.assertion { candidates_exist_for_all_uninstalled? }
+ a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}")
+ a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured")
+ end
+ end
+
+ # Lazy initializer for candidate_version. A nil value means that there is no candidate
+ # version and the package is not installable (generally an error).
+ #
+ # @return [Array] list of candidate_versions indexed same as new_resource.package_name/version
+ def candidate_version
+ @candidate_version ||= build_candidate_versions
+ end
+
+ # Install multiple packages via choco.exe
+ #
+ # @param names [Array<String>] array of package names to install
+ # @param versions [Array<String>] array of versions to install
+ def install_package(names, versions)
+ name_versions_to_install = desired_name_versions.select { |n, v| names.include?(n) }
+
+ name_nil_versions = name_versions_to_install.select { |n,v| v.nil? }
+ name_has_versions = name_versions_to_install.reject { |n,v| v.nil? }
+
+ # choco does not support installing multiple packages with version pins
+ name_has_versions.each do |name, version|
+ choco_command("install -y -version", version, cmd_args, name)
+ end
+
+ # but we can do all the ones without version pins at once
+ unless name_nil_versions.empty?
+ cmd_names = name_nil_versions.keys
+ choco_command("install -y", cmd_args, *cmd_names)
+ end
+ end
+
+ # Upgrade multiple packages via choco.exe
+ #
+ # @param names [Array<String>] array of package names to install
+ # @param versions [Array<String>] array of versions to install
+ def upgrade_package(names, versions)
+ name_versions_to_install = desired_name_versions.select { |n, v| names.include?(n) }
+
+ name_nil_versions = name_versions_to_install.select { |n,v| v.nil? }
+ name_has_versions = name_versions_to_install.reject { |n,v| v.nil? }
+
+ # choco does not support installing multiple packages with version pins
+ name_has_versions.each do |name, version|
+ choco_command("upgrade -y -version", version, cmd_args, name)
+ end
+
+ # but we can do all the ones without version pins at once
+ unless name_nil_versions.empty?
+ cmd_names = name_nil_versions.keys
+ choco_command("upgrade -y", cmd_args, *cmd_names)
+ end
+ end
+
+ # Remove multiple packages via choco.exe
+ #
+ # @param names [Array<String>] array of package names to install
+ # @param versions [Array<String>] array of versions to install
+ def remove_package(names, versions)
+ choco_command("uninstall -y", cmd_args, *names)
+ end
+
+ # Support :uninstall as an action in order for users to easily convert
+ # from the `chocolatey` provider in the cookbook. It is, however,
+ # already deprecated.
+ def action_uninstall
+ Chef::Log.deprecation "The use of action :uninstall on the chocolatey_package provider is deprecated, please use :remove"
+ action_remove
+ end
+
+ # Choco does not have dpkg's distinction between purge and remove
+ alias_method :purge_package, :remove_package
+
+ # Override the superclass check. The semantics for our new_resource.source is not files to
+ # install from, but like the rubygem provider's sources which are more like repos.
+ def check_resource_semantics!
+ end
+
+ private
+
+ # Magic to find where chocolatey is installed in the system, and to
+ # return the full path of choco.exe
+ #
+ # @return [String] full path of choco.exe
+ def choco_exe
+ @choco_exe ||=
+ ::File.join(
+ powershell_out!(
+ "[System.Environment]::GetEnvironmentVariable('ChocolateyInstall', 'MACHINE')"
+ ).stdout.chomp,
+ 'bin',
+ 'choco.exe'
+ )
+ end
+
+ # Helper to dispatch a choco command through shell_out using the timeout
+ # set on the new resource, with nice command formatting.
+ #
+ # @param args [String] variable number of string arguments
+ # @return [Mixlib::ShellOut] object returned from shell_out!
+ def choco_command(*args)
+ shell_out_with_timeout!(args_to_string(choco_exe, *args))
+ end
+
+ # Use the available_packages Hash helper to create an array suitable for
+ # using in candidate_version
+ #
+ # @return [Array] list of candidate_version, same index as new_resource.package_name/version
+ def build_candidate_versions
+ new_resource.package_name.map do |package_name|
+ available_packages[package_name.downcase]
+ end
+ end
+
+ # Use the installed_packages Hash helper to create an array suitable for
+ # using in current_resource.version
+ #
+ # @return [Array] list of candidate_version, same index as new_resource.package_name/version
+ def build_current_versions
+ new_resource.package_name.map do |package_name|
+ installed_packages[package_name.downcase]
+ end
+ end
+
+ # Helper to construct Hash of names-to-versions, requested on the new_resource.
+ # If new_resource.version is nil, then all values will be nil.
+ #
+ # @return [Hash] Mapping of requested names to versions
+ def desired_name_versions
+ desired_versions = new_resource.version || new_resource.package_name.map { nil }
+ Hash[*new_resource.package_name.zip(desired_versions).flatten]
+ end
+
+ # Helper to construct optional args out of new_resource
+ #
+ # @return [String] options from new_resource or empty string
+ def cmd_args
+ cmd_args = [ new_resource.options ]
+ cmd_args.push( "-source #{new_resource.source}" ) if new_resource.source
+ args_to_string(*cmd_args)
+ end
+
+ # Helper to nicely convert variable string args into a single command line. It
+ # will compact nulls or empty strings and join arguments with single spaces, without
+ # introducing any double-spaces for missing args.
+ #
+ # @param args [String] variable number of string arguments
+ # @return [String] nicely concatenated string or empty string
+ def args_to_string(*args)
+ args.reject {|i| i.nil? || i == "" }.join(" ")
+ end
+
+ # Available packages in chocolatey as a Hash of names mapped to versions
+ # If pinning a package to a specific version, filter out all non matching versions
+ # (names are downcased for case-insensitive matching)
+ #
+ # @return [Hash] name-to-version mapping of available packages
+ def available_packages
+ @available_packages ||=
+ begin
+ cmd = [ "list -ar #{package_name_array.join ' '}" ]
+ cmd.push( "-source #{new_resource.source}" ) if new_resource.source
+ parse_list_output(*cmd).reject do |name,version|
+ desired_name_versions[name] && desired_name_versions[name] != version
+ end
+ end
+ end
+
+ # Installed packages in chocolatey as a Hash of names mapped to versions
+ # (names are downcased for case-insensitive matching)
+ #
+ # @return [Hash] name-to-version mapping of installed packages
+ def installed_packages
+ @installed_packages ||= parse_list_output("list -l -r")
+ end
+
+ # Helper to convert choco.exe list output to a Hash
+ # (names are downcased for case-insenstive matching)
+ #
+ # @param cmd [String] command to run
+ # @return [String] list output converted to ruby Hash
+ def parse_list_output(*args)
+ hash = {}
+ choco_command(*args).stdout.each_line do |line|
+ name, version = line.split('|')
+ hash[name.downcase] = version.chomp
+ end
+ hash
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb
index 729f755b2a..0ea739e8d1 100644
--- a/lib/chef/provider/package/rubygems.rb
+++ b/lib/chef/provider/package/rubygems.rb
@@ -137,7 +137,7 @@ class Chef
spec.version
else
# This is probably going to end badly...
- logger.warn { "#{@new_resource} gem package #{source} does not satisfy the requirements #{gem_dependency.to_s}" }
+ logger.warn { "#{@new_resource} gem package #{source} does not satisfy the requirements #{gem_dependency}" }
nil
end
end
@@ -445,7 +445,7 @@ class Chef
logger.debug { "#{@new_resource} newest installed version of gem #{gemspec.name} is #{gemspec.version}" }
gemspec
else
- logger.debug { "#{@new_resource} no installed version found for #{gem_dependency.to_s}"}
+ logger.debug { "#{@new_resource} no installed version found for #{gem_dependency}"}
nil
end
end
diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb
index fc90079846..43972c933c 100644
--- a/lib/chef/provider/package/windows.rb
+++ b/lib/chef/provider/package/windows.rb
@@ -109,7 +109,7 @@ class Chef
io.seek(io.tell() - overlap)
end
end
- end
+ end
# if file is named 'setup.exe' assume installshield
if basename == 'setup.exe'
diff --git a/lib/chef/provider/package/windows/exe.rb b/lib/chef/provider/package/windows/exe.rb
index 3758b8b1e2..8f6cd1efa5 100644
--- a/lib/chef/provider/package/windows/exe.rb
+++ b/lib/chef/provider/package/windows/exe.rb
@@ -48,7 +48,7 @@ class Chef
end
def package_version
- new_resource.version || install_file_version
+ new_resource.version
end
def install_package
@@ -97,18 +97,6 @@ class Chef
end
end
- def install_file_version
- @install_file_version ||= begin
- if !new_resource.source.nil? && ::File.exist?(new_resource.source)
- version_info = Chef::ReservedNames::Win32::File.version_info(new_resource.source)
- file_version = version_info.FileVersion || version_info.ProductVersion
- file_version == '' ? nil : file_version
- else
- nil
- end
- end
- end
-
# http://unattended.sourceforge.net/installers.php
def unattended_flags
case installer_type
diff --git a/lib/chef/provider/remote_file/content.rb b/lib/chef/provider/remote_file/content.rb
index 4f450ce333..01193907a1 100644
--- a/lib/chef/provider/remote_file/content.rb
+++ b/lib/chef/provider/remote_file/content.rb
@@ -55,7 +55,7 @@ class Chef
end
raw_file = grab_file_from_uri(uri)
rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPServerException, Net::HTTPFatalError, Net::FTPError => e
- Chef::Log.warn("#{@new_resource} cannot be downloaded from #{source}: #{e.to_s}")
+ Chef::Log.warn("#{@new_resource} cannot be downloaded from #{source}: #{e}")
if source = sources.shift
Chef::Log.info("#{@new_resource} trying to download from another mirror")
retry
diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb
index d72d135b09..311bb1082e 100644
--- a/lib/chef/provider/service.rb
+++ b/lib/chef/provider/service.rb
@@ -64,7 +64,7 @@ class Chef
def define_resource_requirements
requirements.assert(:reload) do |a|
a.assertion { supports[:reload] || @new_resource.reload_command }
- a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
+ a.failure_message Chef::Exceptions::UnsupportedAction, "#{self} does not support :reload"
# if a service is not declared to support reload, that won't
# typically change during the course of a run - so no whyrun
# alternative here.
@@ -143,27 +143,27 @@ class Chef
end
def enable_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :enable"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :enable"
end
def disable_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :disable"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :disable"
end
def start_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :start"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :start"
end
def stop_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :stop"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :stop"
end
def restart_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :restart"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :restart"
end
def reload_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
+ raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :reload"
end
protected
diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb
index 0a8fca4262..9c733da493 100644
--- a/lib/chef/provider/service/macosx.rb
+++ b/lib/chef/provider/service/macosx.rb
@@ -74,7 +74,7 @@ class Chef
def define_resource_requirements
requirements.assert(:reload) do |a|
- a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
+ a.failure_message Chef::Exceptions::UnsupportedAction, "#{self} does not support :reload"
end
requirements.assert(:all_actions) do |a|
diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb
index d295513b42..bb3d819b3d 100644
--- a/lib/chef/provider/service/simple.rb
+++ b/lib/chef/provider/service/simple.rb
@@ -58,21 +58,21 @@ class Chef
shared_resource_requirements
requirements.assert(:start) do |a|
a.assertion { @new_resource.start_command }
- a.failure_message Chef::Exceptions::Service, "#{self.to_s} requires that start_command be set"
+ a.failure_message Chef::Exceptions::Service, "#{self} requires that start_command be set"
end
requirements.assert(:stop) do |a|
a.assertion { @new_resource.stop_command }
- a.failure_message Chef::Exceptions::Service, "#{self.to_s} requires that stop_command be set"
+ a.failure_message Chef::Exceptions::Service, "#{self} requires that stop_command be set"
end
requirements.assert(:restart) do |a|
a.assertion { @new_resource.restart_command || ( @new_resource.start_command && @new_resource.stop_command ) }
- a.failure_message Chef::Exceptions::Service, "#{self.to_s} requires a restart_command or both start_command and stop_command be set in order to perform a restart"
+ a.failure_message Chef::Exceptions::Service, "#{self} requires a restart_command or both start_command and stop_command be set in order to perform a restart"
end
requirements.assert(:reload) do |a|
a.assertion { @new_resource.reload_command }
- a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} requires a reload_command be set in order to perform a reload"
+ a.failure_message Chef::Exceptions::UnsupportedAction, "#{self} requires a reload_command be set in order to perform a reload"
end
requirements.assert(:all_actions) do |a|
diff --git a/lib/chef/provider/service/windows.rb b/lib/chef/provider/service/windows.rb
index 355ffafc2a..f5c370246c 100644
--- a/lib/chef/provider/service/windows.rb
+++ b/lib/chef/provider/service/windows.rb
@@ -47,6 +47,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
TIMEOUT = 60
+ SERVICE_RIGHT = 'SeServiceLogonRight'
+
def whyrun_supported?
false
end
@@ -78,10 +80,10 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
Win32::Service.configure(new_config)
Chef::Log.info "#{@new_resource} configured with #{new_config.inspect}"
- # it would be nice to check if the user already has the logon privilege, but that turns out to be
- # nontrivial.
if new_config.has_key?(:service_start_name)
- grant_service_logon(new_config[:service_start_name])
+ unless Chef::ReservedNames::Win32::Security.get_account_right(canonicalize_username(new_config[:service_start_name])).include?(SERVICE_RIGHT)
+ grant_service_logon(new_config[:service_start_name])
+ end
end
state = current_state
@@ -236,62 +238,15 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
end
private
- def make_policy_text(username)
- text = <<-EOS
-[Unicode]
-Unicode=yes
-[Privilege Rights]
-SeServiceLogonRight = \\\\#{canonicalize_username(username)},*S-1-5-80-0
-[Version]
-signature="$CHICAGO$"
-Revision=1
-EOS
- end
-
- def grant_logfile_name(username)
- Chef::Util::PathHelper.canonical_path("#{Dir.tmpdir}/logon_grant-#{clean_username_for_path(username)}-#{$$}.log", prefix=false)
- end
-
- def grant_policyfile_name(username)
- Chef::Util::PathHelper.canonical_path("#{Dir.tmpdir}/service_logon_policy-#{clean_username_for_path(username)}-#{$$}.inf", prefix=false)
- end
-
- def grant_dbfile_name(username)
- "#{ENV['TEMP']}\\secedit.sdb"
- end
-
def grant_service_logon(username)
- logfile = grant_logfile_name(username)
- policy_file = ::File.new(grant_policyfile_name(username), 'w')
- policy_text = make_policy_text(username)
- dbfile = grant_dbfile_name(username) # this is just an audit file.
-
begin
- Chef::Log.debug "Policy file text:\n#{policy_text}"
- policy_file.puts(policy_text)
- policy_file.close # need to flush the buffer.
-
- # it would be nice to do this with APIs instead, but the LSA_* APIs are
- # particularly onerous and life is short.
- cmd = %Q{secedit.exe /configure /db "#{dbfile}" /cfg "#{policy_file.path}" /areas USER_RIGHTS SECURITYPOLICY SERVICES /log "#{logfile}"}
- Chef::Log.debug "Granting logon-as-service privilege with: #{cmd}"
- runner = shell_out(cmd)
-
- if runner.exitstatus != 0
- Chef::Log.fatal "Logon-as-service grant failed with output: #{runner.stdout}"
- raise Chef::Exceptions::Service, <<-EOS
-Logon-as-service grant failed with policy file #{policy_file.path}.
-You can look at #{logfile} for details, or do `secedit /analyze #{dbfile}`.
-The failed command was `#{cmd}`.
-EOS
- end
-
- Chef::Log.info "Grant logon-as-service to user '#{username}' successful."
-
- ::File.delete(dbfile) rescue nil
- ::File.delete(policy_file)
- ::File.delete(logfile) rescue nil # logfile is not always present at end.
+ Chef::ReservedNames::Win32::Security.add_account_right(canonicalize_username(username), SERVICE_RIGHT)
+ rescue Chef::Exceptions::Win32APIError => err
+ Chef::Log.fatal "Logon-as-service grant failed with output: #{err}"
+ raise Chef::Exceptions::Service, "Logon-as-service grant failed for #{username}: #{err}"
end
+
+ Chef::Log.info "Grant logon-as-service to user '#{username}' successful."
true
end
@@ -300,8 +255,6 @@ EOS
username.gsub(/[\/\\. ]+/, '_')
end
- # the security policy file only seems to accept \\username, so fix .\username or .\\username.
- # TODO: this probably has to be fixed to handle various valid Windows names correctly.
def canonicalize_username(username)
username.sub(/^\.?\\+/, '')
end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index f5e7a0f989..b4eeabd48d 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -1,6 +1,6 @@
#
# Author:: Daniel DeLeo (<dan@opscode.com>)
-# Copyright:: Copyright (c) 2010 Opscode, Inc.
+# Copyright:: Copyright (c) 2010-2015 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -57,6 +57,7 @@ require 'chef/provider/whyrun_safe_ruby_block'
require 'chef/provider/env/windows'
require 'chef/provider/package/apt'
+require 'chef/provider/package/chocolatey'
require 'chef/provider/package/dpkg'
require 'chef/provider/package/easy_install'
require 'chef/provider/package/freebsd/port'
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 4aec8cf1f6..6b56a0107a 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -658,7 +658,7 @@ class Chef
def inspect
ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
- ivars.inject("<#{to_s}") do |str, ivar|
+ ivars.inject("<#{self}") do |str, ivar|
str << " #{ivar}: #{instance_variable_get(ivar).inspect}"
end << ">"
end
@@ -1332,7 +1332,7 @@ class Chef
if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
enclosing_provider.send(method_symbol, *args, &block)
else
- raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
+ raise NoMethodError, "undefined method `#{method_symbol}' for #{self.class}"
end
end
diff --git a/lib/chef/resource/chocolatey_package.rb b/lib/chef/resource/chocolatey_package.rb
new file mode 100644
index 0000000000..57a6bd2357
--- /dev/null
+++ b/lib/chef/resource/chocolatey_package.rb
@@ -0,0 +1,39 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Copyright:: Copyright (c) 2008-2015 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/resource/package'
+
+class Chef
+ class Resource
+ class ChocolateyPackage < Chef::Resource::Package
+
+ provides :chocolatey_package, os: "windows"
+
+ allowed_actions :install, :upgrade, :remove, :uninstall, :purge, :reconfig
+
+ def initialize(name, run_context=nil)
+ super
+ @resource_name = :chocolatey_package
+ end
+
+ property :package_name, [String, Array], coerce: proc { |x| [x].flatten }
+
+ property :version, [String, Array], coerce: proc { |x| [x].flatten }
+ end
+ end
+end
diff --git a/lib/chef/resource/cron.rb b/lib/chef/resource/cron.rb
index 93cf41bc37..70c2dd89a3 100644
--- a/lib/chef/resource/cron.rb
+++ b/lib/chef/resource/cron.rb
@@ -123,7 +123,7 @@ class Chef
end
begin
error_message = "You provided '#{arg}' as a weekday, acceptable values are "
- error_message << Provider::Cron::WEEKDAY_SYMBOLS.map {|sym| ":#{sym.to_s}"}.join(', ')
+ error_message << Provider::Cron::WEEKDAY_SYMBOLS.map {|sym| ":#{sym}"}.join(', ')
error_message << " and a string in crontab format"
if (arg.is_a?(Symbol) && !Provider::Cron::WEEKDAY_SYMBOLS.include?(arg)) ||
(!arg.is_a?(Symbol) && integerize(arg) > 7) ||
diff --git a/lib/chef/resource/dsc_resource.rb b/lib/chef/resource/dsc_resource.rb
index 0664dc7d7f..6ffa0ca248 100644
--- a/lib/chef/resource/dsc_resource.rb
+++ b/lib/chef/resource/dsc_resource.rb
@@ -1,120 +1,120 @@
-#
-# Author:: Adam Edwards (<adamed@getchef.com>)
-#
-# Copyright:: 2014, Opscode, Inc.
-#
-# 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/dsl/powershell'
-
-class Chef
- class Resource
- class DscResource < Chef::Resource
- provides :dsc_resource, os: "windows"
-
- # This class will check if the object responds to
- # to_text. If it does, it will call that as opposed
- # to inspect. This is useful for properties that hold
- # objects such as PsCredential, where we do not want
- # to dump the actual ivars
- class ToTextHash < Hash
- def to_text
- descriptions = self.map do |(property, obj)|
- obj_text = if obj.respond_to?(:to_text)
- obj.to_text
- else
- obj.inspect
- end
- "#{property}=>#{obj_text}"
- end
- "{#{descriptions.join(', ')}}"
- end
- end
-
- include Chef::DSL::Powershell
-
- default_action :run
-
- def initialize(name, run_context)
- super
- @properties = ToTextHash.new
- @resource = nil
- @reboot_action = :nothing
- end
-
- def resource(value=nil)
- if value
- @resource = value
- else
- @resource
- end
- end
-
- def module_name(value=nil)
- if value
- @module_name = value
- else
- @module_name
- end
- end
-
- def property(property_name, value=nil)
- if not property_name.is_a?(Symbol)
- raise TypeError, "A property name of type Symbol must be specified, '#{property_name.to_s}' of type #{property_name.class.to_s} was given"
- end
-
- if value.nil?
- value_of(@properties[property_name])
- else
- @properties[property_name] = value
- end
- end
-
- def properties
- @properties.reduce({}) do |memo, (k, v)|
- memo[k] = value_of(v)
- memo
- end
- end
-
- # This property takes the action message for the reboot resource
- # If the set method of the DSC resource indicate that a reboot
- # is necessary, reboot_action provides the mechanism for a reboot to
- # be requested.
- def reboot_action(value=nil)
- if value
- @reboot_action = value
- else
- @reboot_action
- end
- end
-
- def timeout(arg=nil)
- set_or_return(
- :timeout,
- arg,
- :kind_of => [ Integer ]
- )
- end
- private
-
- def value_of(value)
- if value.is_a?(DelayedEvaluator)
- value.call
- else
- value
- end
- end
- end
- end
-end
+#
+# Author:: Adam Edwards (<adamed@getchef.com>)
+#
+# Copyright:: 2014, Opscode, Inc.
+#
+# 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/dsl/powershell'
+
+class Chef
+ class Resource
+ class DscResource < Chef::Resource
+ provides :dsc_resource, os: "windows"
+
+ # This class will check if the object responds to
+ # to_text. If it does, it will call that as opposed
+ # to inspect. This is useful for properties that hold
+ # objects such as PsCredential, where we do not want
+ # to dump the actual ivars
+ class ToTextHash < Hash
+ def to_text
+ descriptions = self.map do |(property, obj)|
+ obj_text = if obj.respond_to?(:to_text)
+ obj.to_text
+ else
+ obj.inspect
+ end
+ "#{property}=>#{obj_text}"
+ end
+ "{#{descriptions.join(', ')}}"
+ end
+ end
+
+ include Chef::DSL::Powershell
+
+ default_action :run
+
+ def initialize(name, run_context)
+ super
+ @properties = ToTextHash.new
+ @resource = nil
+ @reboot_action = :nothing
+ end
+
+ def resource(value=nil)
+ if value
+ @resource = value
+ else
+ @resource
+ end
+ end
+
+ def module_name(value=nil)
+ if value
+ @module_name = value
+ else
+ @module_name
+ end
+ end
+
+ def property(property_name, value=nil)
+ if not property_name.is_a?(Symbol)
+ raise TypeError, "A property name of type Symbol must be specified, '#{property_name}' of type #{property_name.class} was given"
+ end
+
+ if value.nil?
+ value_of(@properties[property_name])
+ else
+ @properties[property_name] = value
+ end
+ end
+
+ def properties
+ @properties.reduce({}) do |memo, (k, v)|
+ memo[k] = value_of(v)
+ memo
+ end
+ end
+
+ # This property takes the action message for the reboot resource
+ # If the set method of the DSC resource indicate that a reboot
+ # is necessary, reboot_action provides the mechanism for a reboot to
+ # be requested.
+ def reboot_action(value=nil)
+ if value
+ @reboot_action = value
+ else
+ @reboot_action
+ end
+ end
+
+ def timeout(arg=nil)
+ set_or_return(
+ :timeout,
+ arg,
+ :kind_of => [ Integer ]
+ )
+ end
+ private
+
+ def value_of(value)
+ if value.is_a?(DelayedEvaluator)
+ value.call
+ else
+ value
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb
index ba0bb08201..e7530ce628 100644
--- a/lib/chef/resource/file/verification.rb
+++ b/lib/chef/resource/file/verification.rb
@@ -28,7 +28,7 @@ class Chef
# See RFC 027 for a full specification
#
# File verifications allow user-supplied commands a means of
- # preventing file reosurce content deploys. Their intended use
+ # preventing file resource content deploys. Their intended use
# is to verify the contents of a temporary file before it is
# deployed onto the system.
#
diff --git a/lib/chef/resource/windows_script.rb b/lib/chef/resource/windows_script.rb
index 2bbd01d5aa..2dff4cde31 100644
--- a/lib/chef/resource/windows_script.rb
+++ b/lib/chef/resource/windows_script.rb
@@ -57,7 +57,7 @@ class Chef
"cannot execute script with requested architecture 'i386' on Windows Nano Server"
elsif ! node_supports_windows_architecture?(node, desired_architecture)
raise Chef::Exceptions::Win32ArchitectureIncorrect,
- "cannot execute script with requested architecture '#{desired_architecture.to_s}' on a system with architecture '#{node_windows_architecture(node)}'"
+ "cannot execute script with requested architecture '#{desired_architecture}' on a system with architecture '#{node_windows_architecture(node)}'"
end
end
end
diff --git a/lib/chef/resource_definition.rb b/lib/chef/resource_definition.rb
index cffabb6786..43350dda2b 100644
--- a/lib/chef/resource_definition.rb
+++ b/lib/chef/resource_definition.rb
@@ -62,7 +62,7 @@ class Chef
end
def to_s
- "#{name.to_s}"
+ "#{name}"
end
end
end
diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb
index 1175b0afb3..e2c71f7bd5 100644
--- a/lib/chef/resource_reporter.rb
+++ b/lib/chef/resource_reporter.rb
@@ -121,7 +121,7 @@ class Chef
if reporting_enabled?
begin
resource_history_url = "reports/nodes/#{node_name}/runs"
- server_response = @rest_client.post_rest(resource_history_url, {:action => :start, :run_id => run_id,
+ server_response = @rest_client.post(resource_history_url, {:action => :start, :run_id => run_id,
:start_time => start_time.to_s}, headers)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
handle_error_starting_run(e, resource_history_url)
@@ -230,10 +230,9 @@ class Chef
Chef::Log.debug run_data.inspect
compressed_data = encode_gzip(Chef::JSONCompat.to_json(run_data))
Chef::Log.debug("Sending compressed run data...")
- # Since we're posting compressed data we can not directly call post_rest which expects JSON
- reporting_url = @rest_client.create_url(resource_history_url)
+ # Since we're posting compressed data we can not directly call post which expects JSON
begin
- @rest_client.raw_http_request(:POST, reporting_url, headers({'Content-Encoding' => 'gzip'}), compressed_data)
+ @rest_client.raw_request(:POST, resource_history_url, headers({'Content-Encoding' => 'gzip'}), compressed_data)
rescue StandardError => e
if e.respond_to? :response
Chef::FileCache.store("failed-reporting-data.json", Chef::JSONCompat.to_json_pretty(run_data), 0640)
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index f699d95ace..cc5b9be8c6 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -1,6 +1,6 @@
#
# Author:: Daniel DeLeo (<dan@opscode.com>)
-# Copyright:: Copyright (c) 2010 Opscode, Inc.
+# Copyright:: Copyright (c) 2010-2015 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +22,7 @@ require 'chef/resource/batch'
require 'chef/resource/breakpoint'
require 'chef/resource/cookbook_file'
require 'chef/resource/chef_gem'
+require 'chef/resource/chocolatey_package'
require 'chef/resource/cron'
require 'chef/resource/csh'
require 'chef/resource/deploy'
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index c085d1d714..6984a8a245 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -24,6 +24,7 @@ require 'chef/mixin/from_file'
require 'chef/run_list'
require 'chef/mash'
require 'chef/json_compat'
+require 'chef/server_api'
require 'chef/search/query'
class Chef
@@ -45,11 +46,11 @@ class Chef
end
def chef_server_rest
- @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
def name(arg=nil)
@@ -170,6 +171,10 @@ class Chef
# Create a Chef::Role from JSON
def self.json_create(o)
+ from_hash(o)
+ end
+
+ def self.from_hash(o)
role = new
role.name(o["name"])
role.description(o["description"])
@@ -199,42 +204,42 @@ class Chef
end
response
else
- chef_server_rest.get_rest("roles")
+ chef_server_rest.get("roles")
end
end
# Load a role by name from the API
def self.load(name)
- chef_server_rest.get_rest("roles/#{name}")
+ from_hash(chef_server_rest.get("roles/#{name}"))
end
def environment(env_name)
- chef_server_rest.get_rest("roles/#{@name}/environments/#{env_name}")
+ chef_server_rest.get("roles/#{@name}/environments/#{env_name}")
end
def environments
- chef_server_rest.get_rest("roles/#{@name}/environments")
+ chef_server_rest.get("roles/#{@name}/environments")
end
# Remove this role via the REST API
def destroy
- chef_server_rest.delete_rest("roles/#{@name}")
+ chef_server_rest.delete("roles/#{@name}")
end
# Save this role via the REST API
def save
begin
- chef_server_rest.put_rest("roles/#{@name}", self)
+ chef_server_rest.put("roles/#{@name}", self)
rescue Net::HTTPServerException => e
raise e unless e.response.code == "404"
- chef_server_rest.post_rest("roles", self)
+ chef_server_rest.post("roles", self)
end
self
end
# Create the role via the REST API
def create
- chef_server_rest.post_rest("roles", self)
+ chef_server_rest.post("roles", self)
self
end
@@ -258,7 +263,8 @@ class Chef
if js_path && File.exists?(js_path)
# from_json returns object.class => json_class in the JSON.
- return Chef::JSONCompat.from_json(IO.read(js_path))
+ hsh = Chef::JSONCompat.parse(IO.read(js_path))
+ return from_hash(hsh)
elsif rb_path && File.exists?(rb_path)
role = Chef::Role.new
role.name(name)
diff --git a/lib/chef/run_list/run_list_expansion.rb b/lib/chef/run_list/run_list_expansion.rb
index 64e4326fb8..2f2d170446 100644
--- a/lib/chef/run_list/run_list_expansion.rb
+++ b/lib/chef/run_list/run_list_expansion.rb
@@ -21,7 +21,7 @@ require 'chef/mash'
require 'chef/mixin/deep_merge'
require 'chef/role'
-require 'chef/rest'
+require 'chef/server_api'
require 'chef/json_compat'
class Chef
@@ -45,7 +45,7 @@ class Chef
attr_reader :missing_roles_with_including_role
# The data source passed to the constructor. Not used in this class.
- # In subclasses, this is a couchdb or Chef::REST object pre-configured
+ # In subclasses, this is a Chef::ServerAPI object pre-configured
# to fetch roles from their correct location.
attr_reader :source
@@ -214,11 +214,11 @@ class Chef
class RunListExpansionFromAPI < RunListExpansion
def rest
- @rest ||= (source || Chef::REST.new(Chef::Config[:chef_server_url]))
+ @rest ||= (source || Chef::ServerAPI.new(Chef::Config[:chef_server_url]))
end
def fetch_role(name, included_by)
- rest.get_rest("roles/#{name}")
+ Chef::Role.from_hash(rest.get("roles/#{name}"))
rescue Net::HTTPServerException => e
if e.message == '404 "Not Found"'
role_not_found(name, included_by)
diff --git a/lib/chef/search/query.rb b/lib/chef/search/query.rb
index 658af8779c..c5c6bc6ce0 100644
--- a/lib/chef/search/query.rb
+++ b/lib/chef/search/query.rb
@@ -18,7 +18,7 @@
require 'chef/config'
require 'chef/exceptions'
-require 'chef/rest'
+require 'chef/server_api'
require 'uri'
@@ -35,7 +35,7 @@ class Chef
end
def rest
- @rest ||= Chef::REST.new(@url || @config[:chef_server_url])
+ @rest ||= Chef::ServerAPI.new(@url || @config[:chef_server_url])
end
# Backwards compatability for cookbooks.
@@ -150,12 +150,26 @@ WARNDEP
query_string = create_query_string(type, query, rows, start, sort)
if filter_result
- response = rest.post_rest(query_string, filter_result)
+ response = rest.post(query_string, filter_result)
# response returns rows in the format of
# { "url" => url_to_node, "data" => filter_result_hash }
response['rows'].map! { |row| row['data'] }
else
- response = rest.get_rest(query_string)
+ response = rest.get(query_string)
+ response['rows'].map! do |row|
+ case type.to_s
+ when 'node'
+ Chef::Node.from_hash(row)
+ when 'role'
+ Chef::Role.from_hash(row)
+ when 'environment'
+ Chef::Environment.from_hash(row)
+ when 'client'
+ Chef::ApiClient.from_hash(row)
+ else
+ Chef::DataBagItem.from_hash(row)
+ end
+ end
end
response
diff --git a/lib/chef/server_api.rb b/lib/chef/server_api.rb
index 764296f8c8..6c864d53fb 100644
--- a/lib/chef/server_api.rb
+++ b/lib/chef/server_api.rb
@@ -23,6 +23,7 @@ require 'chef/http/decompressor'
require 'chef/http/json_input'
require 'chef/http/json_output'
require 'chef/http/remote_request_id'
+require 'chef/http/validate_content_length'
class Chef
class ServerAPI < Chef::HTTP
@@ -31,6 +32,7 @@ class Chef
options[:client_name] ||= Chef::Config[:node_name]
options[:signing_key_filename] ||= Chef::Config[:client_key]
options[:signing_key_filename] = nil if chef_zero_uri?(url)
+ options[:inflate_json_class] = false
super(url, options)
end
@@ -40,6 +42,30 @@ class Chef
use Chef::HTTP::Decompressor
use Chef::HTTP::Authenticator
use Chef::HTTP::RemoteRequestID
+
+ # ValidateContentLength should come after Decompressor
+ # because the order of middlewares is reversed when handling
+ # responses.
+ use Chef::HTTP::ValidateContentLength
+
+ # Makes an HTTP request to +path+ with the given +method+, +headers+, and
+ # +data+ (if applicable). Does not apply any middleware, besides that
+ # needed for Authentication.
+ def raw_request(method, path, headers={}, data=false)
+ url = create_url(path)
+ method, url, headers, data = Chef::HTTP::Authenticator.new(options).handle_request(method, url, headers, data)
+ method, url, headers, data = Chef::HTTP::RemoteRequestID.new(options).handle_request(method, url, headers, data)
+ response, rest_request, return_value = send_http_request(method, url, headers, data)
+ response.error! unless success_response?(response)
+ return_value
+ rescue Exception => exception
+ log_failed_request(response, return_value) unless response.nil?
+
+ if exception.respond_to?(:chef_rest_request=)
+ exception.chef_rest_request = rest_request
+ end
+ raise
+ end
end
end
diff --git a/lib/chef/shell/ext.rb b/lib/chef/shell/ext.rb
index d516524765..ae013de76b 100644
--- a/lib/chef/shell/ext.rb
+++ b/lib/chef/shell/ext.rb
@@ -23,7 +23,7 @@ require 'chef/dsl/platform_introspection'
require 'chef/version'
require 'chef/shell/shell_session'
require 'chef/shell/model_wrapper'
-require 'chef/shell/shell_rest'
+require 'chef/server_api'
require 'chef/json_compat'
module Shell
@@ -331,7 +331,7 @@ E
edited_data = Tempfile.open([filename, ".js"]) do |tempfile|
tempfile.sync = true
tempfile.puts Chef::JSONCompat.to_json(object)
- system("#{Shell.editor.to_s} #{tempfile.path}")
+ system("#{Shell.editor} #{tempfile.path}")
tempfile.rewind
tempfile.read
end
@@ -536,7 +536,7 @@ E
desc "A REST Client configured to authenticate with the API"
def api
- @rest = Shell::ShellREST.new(Chef::Config[:chef_server_url])
+ @rest = Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
end
diff --git a/lib/chef/shell/shell_rest.rb b/lib/chef/shell/shell_rest.rb
deleted file mode 100644
index a485a0a1a8..0000000000
--- a/lib/chef/shell/shell_rest.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-#--
-# Author:: Daniel DeLeo (<dan@opscode.com>)
-# Copyright:: Copyright (c) 2010 Opscode, 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.
-#
-
-module Shell
- class ShellREST < Chef::REST
-
- alias :get :get_rest
- alias :put :put_rest
- alias :post :post_rest
- alias :delete :delete_rest
-
- end
-end
diff --git a/lib/chef/shell/shell_session.rb b/lib/chef/shell/shell_session.rb
index 73e6c34ebb..7b3939da69 100644
--- a/lib/chef/shell/shell_session.rb
+++ b/lib/chef/shell/shell_session.rb
@@ -201,7 +201,7 @@ module Shell
def rebuild_context
@run_status = Chef::RunStatus.new(@node, @events)
- Chef::Cookbook::FileVendor.fetch_from_remote(Chef::REST.new(Chef::Config[:chef_server_url]))
+ Chef::Cookbook::FileVendor.fetch_from_remote(Chef::ServerAPI.new(Chef::Config[:chef_server_url]))
cookbook_hash = @client.sync_cookbooks
cookbook_collection = Chef::CookbookCollection.new(cookbook_hash)
@run_context = Chef::RunContext.new(node, cookbook_collection, @events)
@@ -253,7 +253,8 @@ module Shell
end
def register
- @rest = Chef::REST.new(Chef::Config[:chef_server_url], Chef::Config[:node_name], Chef::Config[:client_key])
+ @rest = Chef::ServerAPI.new(Chef::Config[:chef_server_url], :client_name => Chef::Config[:node_name],
+ :signing_key_filename => Chef::Config[:client_key])
end
end
diff --git a/lib/chef/user_v1.rb b/lib/chef/user_v1.rb
index 31cb0576a2..077fca50b9 100644
--- a/lib/chef/user_v1.rb
+++ b/lib/chef/user_v1.rb
@@ -140,7 +140,7 @@ class Chef
def destroy
# will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
- Chef::REST.new(Chef::Config[:chef_server_url]).delete("users/#{@username}")
+ Chef::ServerAPI.new(Chef::Config[:chef_server_url]).delete("users/#{@username}")
end
def create
@@ -287,7 +287,7 @@ class Chef
end
def self.list(inflate=false)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get('users')
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get('users')
users = if response.is_a?(Array)
# EC 11 / CS 12 V0, V1
# GET /organizations/<org>/users
@@ -312,7 +312,7 @@ class Chef
def self.load(username)
# will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get("users/#{username}")
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("users/#{username}")
Chef::UserV1.from_hash(response)
end
diff --git a/lib/chef/util/dsc/configuration_generator.rb b/lib/chef/util/dsc/configuration_generator.rb
index 0d7296eae9..2041278e4a 100644
--- a/lib/chef/util/dsc/configuration_generator.rb
+++ b/lib/chef/util/dsc/configuration_generator.rb
@@ -72,7 +72,7 @@ class Chef::Util::DSC
if configuration_flags
configuration_flags.map do | switch, value |
if merged_configuration_flags.key?(switch.to_s.downcase.to_sym)
- raise ArgumentError, "The `flags` attribute for the dsc_script resource contained a command line switch :#{switch.to_s} that is disallowed."
+ raise ArgumentError, "The `flags` attribute for the dsc_script resource contained a command line switch :#{switch} that is disallowed."
end
merged_configuration_flags[switch.to_s.downcase.to_sym] = value
end
diff --git a/lib/chef/util/powershell/cmdlet.rb b/lib/chef/util/powershell/cmdlet.rb
index 47d63a2b85..7eab098c83 100644
--- a/lib/chef/util/powershell/cmdlet.rb
+++ b/lib/chef/util/powershell/cmdlet.rb
@@ -38,7 +38,7 @@ class Powershell
when :object
@json_format = true
else
- raise ArgumentError, "Invalid output format #{output_format.to_s} specified"
+ raise ArgumentError, "Invalid output format #{output_format} specified"
end
@cmdlet = cmdlet
@@ -114,7 +114,7 @@ class Powershell
def command_switches_string(switches)
command_switches = switches.map do | switch_name, switch_value |
if switch_name.class != Symbol
- raise ArgumentError, "Invalid type `#{switch_name} `for PowerShell switch '#{switch_name.to_s}'. The switch must be specified as a Symbol'"
+ raise ArgumentError, "Invalid type `#{switch_name} `for PowerShell switch '#{switch_name}'. The switch must be specified as a Symbol'"
end
validate_switch_name!(switch_name)
@@ -133,7 +133,7 @@ class Powershell
when String
switch_argument = escape_string_parameter_value(switch_value)
else
- raise ArgumentError, "Invalid argument type `#{switch_value.class}` specified for PowerShell switch `:#{switch_name.to_s}`. Arguments to PowerShell must be of type `String`, `Numeric`, `Float`, `FalseClass`, or `TrueClass`"
+ raise ArgumentError, "Invalid argument type `#{switch_value.class}` specified for PowerShell switch `:#{switch_name}`. Arguments to PowerShell must be of type `String`, `Numeric`, `Float`, `FalseClass`, or `TrueClass`"
end
switch_present ? ["-#{switch_name.to_s.downcase}", switch_argument].join(' ').strip : ''
diff --git a/lib/chef/version/platform.rb b/lib/chef/version/platform.rb
index 81e7614646..d9028b5d15 100644
--- a/lib/chef/version/platform.rb
+++ b/lib/chef/version/platform.rb
@@ -34,7 +34,7 @@ class Chef
when /^(\d+).(\d+)-[a-z]+\d?(-p(\d+))?$/i # Match FreeBSD
[ $1.to_i, $2.to_i, ($4 ? $4.to_i : 0)]
else
- msg = "'#{str.to_s}' does not match 'x.y.z', 'x.y' or 'x'"
+ msg = "'#{str}' does not match 'x.y.z', 'x.y' or 'x'"
raise Chef::Exceptions::InvalidPlatformVersion.new( msg )
end
end
diff --git a/lib/chef/version_class.rb b/lib/chef/version_class.rb
index 01af6f1f55..913c50442d 100644
--- a/lib/chef/version_class.rb
+++ b/lib/chef/version_class.rb
@@ -61,7 +61,7 @@ class Chef
when /^(\d+)\.(\d+)$/
[ $1.to_i, $2.to_i, 0 ]
else
- msg = "'#{str.to_s}' does not match 'x.y.z' or 'x.y'"
+ msg = "'#{str}' does not match 'x.y.z' or 'x.y'"
raise Chef::Exceptions::InvalidCookbookVersion.new( msg )
end
end
diff --git a/lib/chef/version_constraint.rb b/lib/chef/version_constraint.rb
index a78e32e94f..ba2169c8cb 100644
--- a/lib/chef/version_constraint.rb
+++ b/lib/chef/version_constraint.rb
@@ -50,7 +50,7 @@ class Chef
end
def inspect
- "(#{to_s})"
+ "(#{self})"
end
def to_s
diff --git a/lib/chef/win32/api.rb b/lib/chef/win32/api.rb
index 4786222bd4..de3381c5ba 100644
--- a/lib/chef/win32/api.rb
+++ b/lib/chef/win32/api.rb
@@ -147,6 +147,8 @@ class Chef
host.typedef :long, :LRESULT # Signed result of message processing. WinDef.h: host.typedef LONG_PTR LRESULT;
host.typedef :pointer, :LPWIN32_FIND_DATA # Pointer to WIN32_FIND_DATA struct
host.typedef :pointer, :LPBY_HANDLE_FILE_INFORMATION # Point to a BY_HANDLE_FILE_INFORMATION struct
+ host.typedef :pointer, :LSA_HANDLE # A handle to a Policy object
+ host.typedef :ulong, :NTSTATUS # An NTSTATUS code returned by an LSA function call.
host.typedef :pointer, :PBOOL # Pointer to a BOOL.
host.typedef :pointer, :PBOOLEAN # Pointer to a BOOL.
host.typedef :pointer, :PBYTE # Pointer to a BYTE.
@@ -174,12 +176,16 @@ class Chef
host.typedef :pointer, :PLONG_PTR # Pointer to a LONG_PTR.
host.typedef :pointer, :PLONG32 # Pointer to a LONG32.
host.typedef :pointer, :PLONG64 # Pointer to a LONG64.
+ host.typedef :pointer, :PLSA_HANDLE # Pointer to an LSA_HANDLE
+ host.typedef :pointer, :PLSA_OBJECT_ATTRIBUTES # Pointer to an LSA_OBJECT_ATTRIBUTES
+ host.typedef :pointer, :PLSA_UNICODE_STRING # Pointer to LSA_UNICODE_STRING
host.typedef :pointer, :PLUID # Pointer to a LUID.
host.typedef :pointer, :POINTER_32 # 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer.
host.typedef :pointer, :POINTER_64 # 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer.
host.typedef :pointer, :POINTER_SIGNED # A signed pointer.
host.typedef :pointer, :POINTER_UNSIGNED # An unsigned pointer.
host.typedef :pointer, :PSHORT # Pointer to a SHORT.
+ host.typedef :pointer, :PSID # Pointer to an account SID
host.typedef :pointer, :PSIZE_T # Pointer to a SIZE_T.
host.typedef :pointer, :PSSIZE_T # Pointer to a SSIZE_T.
host.typedef :pointer, :PSTR # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
@@ -188,7 +194,6 @@ class Chef
host.typedef :pointer, :PCRYPTPROTECT_PROMPTSTRUCT # Pointer to a CRYPTOPROTECT_PROMPTSTRUCT.
host.typedef :pointer, :PDATA_BLOB # Pointer to a DATA_BLOB.
host.typedef :pointer, :PTSTR # A PWSTR if UNICODE is defined, a PSTR otherwise.
- host.typedef :pointer, :PSID
host.typedef :pointer, :PUCHAR # Pointer to a UCHAR.
host.typedef :pointer, :PUHALF_PTR # Pointer to a UHALF_PTR.
host.typedef :pointer, :PUINT # Pointer to a UINT.
diff --git a/lib/chef/win32/api/security.rb b/lib/chef/win32/api/security.rb
index 4c352a3554..4353c488f8 100644
--- a/lib/chef/win32/api/security.rb
+++ b/lib/chef/win32/api/security.rb
@@ -207,6 +207,21 @@ class Chef
LOGON32_PROVIDER_WINNT40 = 2;
LOGON32_PROVIDER_WINNT50 = 3;
+ # LSA access policy
+ POLICY_VIEW_LOCAL_INFORMATION = 0x00000001
+ POLICY_VIEW_AUDIT_INFORMATION = 0x00000002
+ POLICY_GET_PRIVATE_INFORMATION = 0x00000004
+ POLICY_TRUST_ADMIN = 0x00000008
+ POLICY_CREATE_ACCOUNT = 0x00000010
+ POLICY_CREATE_SECRET = 0x00000020
+ POLICY_CREATE_PRIVILEGE = 0x00000040
+ POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080
+ POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100
+ POLICY_AUDIT_LOG_ADMIN = 0x00000200
+ POLICY_SERVER_ADMIN = 0x00000400
+ POLICY_LOOKUP_NAMES = 0x00000800
+ POLICY_NOTIFICATION = 0x00001000
+
###############################################
# Win32 API Bindings
###############################################
@@ -381,6 +396,23 @@ class Chef
end
end
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms721829(v=vs.85).aspx
+ class LSA_OBJECT_ATTRIBUTES < FFI::Struct
+ layout :Length, :ULONG,
+ :RootDirectory, :HANDLE,
+ :ObjectName, :pointer,
+ :Attributes, :ULONG,
+ :SecurityDescriptor, :PVOID,
+ :SecurityQualityOfService, :PVOID
+ end
+
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms721841(v=vs.85).aspx
+ class LSA_UNICODE_STRING < FFI::Struct
+ layout :Length, :USHORT,
+ :MaximumLength, :USHORT,
+ :Buffer, :PWSTR
+ end
+
ffi_lib "advapi32"
safe_attach_function :AccessCheck, [:pointer, :HANDLE, :DWORD, :pointer, :pointer, :pointer, :pointer, :pointer], :BOOL
@@ -415,6 +447,12 @@ class Chef
safe_attach_function :LookupPrivilegeNameW, [ :LPCWSTR, :PLUID, :LPWSTR, :LPDWORD ], :BOOL
safe_attach_function :LookupPrivilegeDisplayNameW, [ :LPCWSTR, :LPCWSTR, :LPWSTR, :LPDWORD, :LPDWORD ], :BOOL
safe_attach_function :LookupPrivilegeValueW, [ :LPCWSTR, :LPCWSTR, :PLUID ], :BOOL
+ safe_attach_function :LsaAddAccountRights, [ :pointer, :pointer, :pointer, :ULONG ], :NTSTATUS
+ safe_attach_function :LsaClose, [ :LSA_HANDLE ], :NTSTATUS
+ safe_attach_function :LsaEnumerateAccountRights, [ :LSA_HANDLE, :PSID, :PLSA_UNICODE_STRING, :PULONG ], :NTSTATUS
+ safe_attach_function :LsaFreeMemory, [ :PVOID ], :NTSTATUS
+ safe_attach_function :LsaNtStatusToWinError, [ :NTSTATUS ], :ULONG
+ safe_attach_function :LsaOpenPolicy, [ :PLSA_UNICODE_STRING, :PLSA_OBJECT_ATTRIBUTES, :DWORD, :PLSA_HANDLE ], :NTSTATUS
safe_attach_function :MakeAbsoluteSD, [ :pointer, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD], :BOOL
safe_attach_function :MapGenericMask, [ :PDWORD, :PGENERICMAPPING ], :void
safe_attach_function :OpenProcessToken, [ :HANDLE, :DWORD, :PHANDLE ], :BOOL
diff --git a/lib/chef/win32/error.rb b/lib/chef/win32/error.rb
index 2175608eeb..c638773d2a 100644
--- a/lib/chef/win32/error.rb
+++ b/lib/chef/win32/error.rb
@@ -57,8 +57,7 @@ class Chef
# nil::: always returns nil when it does not raise
# === Raises
# Chef::Exceptions::Win32APIError:::
- def self.raise!(message = nil)
- code = get_last_error
+ def self.raise!(message = nil, code = get_last_error)
msg = format_message(code).strip
formatted_message = ""
formatted_message << message if message
diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb
index bc80517d80..38694c9fec 100644
--- a/lib/chef/win32/security.rb
+++ b/lib/chef/win32/security.rb
@@ -104,6 +104,22 @@ class Chef
end
end
+ def self.add_account_right(name, privilege)
+ privilege_pointer = FFI::MemoryPointer.new LSA_UNICODE_STRING, 1
+ privilege_lsa_string = LSA_UNICODE_STRING.new(privilege_pointer)
+ privilege_lsa_string[:Buffer] = FFI::MemoryPointer.from_string(privilege.to_wstring)
+ privilege_lsa_string[:Length] = privilege.length * 2
+ privilege_lsa_string[:MaximumLength] = (privilege.length + 1) * 2
+
+ with_lsa_policy(name) do |policy_handle, sid|
+ result = LsaAddAccountRights(policy_handle.read_pointer, sid, privilege_pointer, 1)
+ win32_error = LsaNtStatusToWinError(result)
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+ end
+ end
+
def self.adjust_token_privileges(token, privileges)
token = token.handle if token.respond_to?(:handle)
old_privileges_size = FFI::Buffer.new(:long).write_long(privileges.size_with_privileges)
@@ -165,6 +181,29 @@ class Chef
end
end
+ def self.get_account_right(name)
+ privileges = []
+ privilege_pointer = FFI::MemoryPointer.new(:pointer)
+ privilege_length = FFI::MemoryPointer.new(:ulong)
+
+ with_lsa_policy(name) do |policy_handle, sid|
+ result = LsaEnumerateAccountRights(policy_handle.read_pointer, sid, privilege_pointer, privilege_length)
+ win32_error = LsaNtStatusToWinError(result)
+ return [] if win32_error == 2 # FILE_NOT_FOUND - No rights assigned
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+
+ privilege_length.read_ulong.times do |i|
+ privilege = LSA_UNICODE_STRING.new(privilege_pointer.read_pointer + i * LSA_UNICODE_STRING.size)
+ privileges << privilege[:Buffer].read_wstring
+ end
+ LsaFreeMemory(privilege_pointer)
+ end
+
+ privileges
+ end
+
def self.get_ace(acl, index)
acl = acl.pointer if acl.respond_to?(:pointer)
ace = FFI::Buffer.new :pointer
@@ -548,6 +587,30 @@ class Chef
end
end
+ def self.with_lsa_policy(username)
+ sid = lookup_account_name(username)[1]
+
+ access = 0
+ access |= POLICY_CREATE_ACCOUNT
+ access |= POLICY_LOOKUP_NAMES
+
+ policy_handle = FFI::MemoryPointer.new(:pointer)
+ result = LsaOpenPolicy(nil, LSA_OBJECT_ATTRIBUTES.new, access, policy_handle)
+ win32_error = LsaNtStatusToWinError(result)
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+
+ begin
+ yield policy_handle, sid.pointer
+ ensure
+ win32_error = LsaNtStatusToWinError(LsaClose(policy_handle.read_pointer))
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+ end
+ end
+
def self.with_privileges(*privilege_names)
# Set privileges
token = open_current_process_token(TOKEN_READ | TOKEN_ADJUST_PRIVILEGES)