summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-10-24 23:56:29 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2015-10-24 23:56:29 -0700
commit798339fd64729224a27cedd4e4aeb87e47fd1e92 (patch)
treeda762f76f14ef0a6dd92eacbe849d0220fe9d4b9
parent12c8f798ddf94c99943c71f8dbf55ed8b193a3c0 (diff)
parent1bebe8c4d9199490b8bde182f476a0375d053c22 (diff)
downloadchef-798339fd64729224a27cedd4e4aeb87e47fd1e92.tar.gz
Merge pull request #4105 from chef/lcg/merges
Lcg/merges
-rw-r--r--.gitignore3
-rw-r--r--CHANGELOG.md30
-rw-r--r--lib/chef/api_client/registration.rb3
-rw-r--r--lib/chef/application/apply.rb1
-rw-r--r--lib/chef/digester.rb6
-rw-r--r--lib/chef/exceptions.rb5
-rw-r--r--lib/chef/knife/bootstrap.rb45
-rw-r--r--lib/chef/knife/cookbook_site_install.rb6
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb2
-rw-r--r--lib/chef/knife/ssh.rb12
-rw-r--r--lib/chef/knife/status.rb15
-rw-r--r--lib/chef/node.rb8
-rw-r--r--lib/chef/provider/deploy.rb2
-rw-r--r--lib/chef/provider/execute.rb11
-rw-r--r--lib/chef/provider/group.rb2
-rw-r--r--lib/chef/resource/registry_key.rb2
-rw-r--r--lib/chef/resource/resource_notification.rb15
-rw-r--r--spec/unit/knife/bootstrap_spec.rb39
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb2
-rw-r--r--spec/unit/knife/status_spec.rb26
-rw-r--r--spec/unit/node_spec.rb8
-rw-r--r--spec/unit/provider/deploy_spec.rb2
-rw-r--r--spec/unit/provider/execute_spec.rb9
-rw-r--r--spec/unit/resource/registry_key_spec.rb4
-rw-r--r--spec/unit/resource/resource_notification_spec.rb89
-rw-r--r--spec/unit/rest_spec.rb4
26 files changed, 263 insertions, 88 deletions
diff --git a/.gitignore b/.gitignore
index 39962d2f5f..953f58919f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,6 @@ Vagrantfile
# Kitchen Tests Local Mode Data
kitchen-tests/nodes/*
+
+# Temporary files present during spec runs
+spec/data/test-dir
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2c5223eec..00041ca584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,35 @@
[pr#3263](https://github.com/chef/chef/pull/3263) `value_for_platform` should use `Chef::VersionConstraint::Platform`
* [**Scott McGillivray**](https://github.com/thechile)
[pr#3450](https://github.com/chef/chef/pull/3450) Fix 'knife cookbook show' to work on root files
-
+* [**Aubrey Holland**](https://github.com/aub)
+ [pr#3986](https://github.com/chef/chef/pull/3986) fix errors when files go away during chown
+* [**James Michael DuPont**](https://github.com/h4ck3rm1k3)
+ [pr#3973](https://github.com/chef/chef/pull/3973) better error reporting
+* [**Michael Pereira**](https://github.com/MichaelPereira)
+ [pr#3968](https://github.com/chef/chef/pull/3968) Fix cookbook installation from supermarket on windows
+* [**Yukihiko SAWANOBORI**](https://github.com/sawanoboly)
+ [pr#3941](https://github.com/chef/chef/pull/3941) allow reboot by reboot resource with chef-apply
+* [**permyakovsv**](https://github.com/permyakovsv)
+ [pr#3901](https://github.com/chef/chef/pull/3901) Add tmux-split parameter to knife ssh
+* [**Yukihiko SAWANOBORI**](https://github.com/sawanoboly)
+ [pr#3900](https://github.com/chef/chef/pull/3900) Add new option json attributes file to bootstraping
+* [**Evan Gilman**](https://github.com/evan2645)
+ [pr#3864](https://github.com/chef/chef/pull/3864) Knife `bootstrap_environment` should use Explicit config before Implicit
+* [**Ranjib Dey**](https://github.com/ranjib)
+ [pr#3834](https://github.com/chef/chef/pull/3834) Dont spit out stdout and stderr for execute resource failure, if its declared sensitive
+* [**Jeff Blaine**](https://github.com/jblaine)
+ [pr#3776](https://github.com/chef/chef/pull/3776) Changes --hide-healthy to --hide-by-mins MINS
+* [**dbresson**](https://github.com/dbresson)
+ [pr#3650](https://github.com/chef/chef/pull/3650) Define == for node objects
+* [**Jordan Evans**](https://github.com/jordane)
+ [pr#3633](https://github.com/chef/chef/pull/3633) add the word group to `converge_by` call for group provider
+* [**Patrick Connolly**](https://github.com/patcon)
+ [pr#3529](https://github.com/chef/chef/pull/3529) Allow user@hostname format for knife-bootstrap
+
+* [pr#3530](https://github.com/chef/chef/pull/3530) Allow using --sudo option with user's home folder in knife bootstrap
+* [pr#3858](https://github.com/chef/chef/pull/3858) Remove duplicate 'Accept' header in spec
+* [pr#3911](https://github.com/chef/chef/pull/3911) Avoid subclassing Struct.new
+* [pr#3990](https://github.com/chef/chef/pull/3990) Use SHA256 instead of MD5 for `registry_key` when data is not displayable
* [pr#4034](https://github.com/chef/chef/pull/4034) add optional ruby-profiling with --profile-ruby
* [pr#3119](https://github.com/chef/chef/pull/3119) allow removing user, even if their GID isn't resolvable
* [pr#4068](https://github.com/chef/chef/pull/4068) update messaging from LWRP to Custom Resource in logging and spec
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb
index de5fc7ac3d..4882323293 100644
--- a/lib/chef/api_client/registration.rb
+++ b/lib/chef/api_client/registration.rb
@@ -68,7 +68,8 @@ class Chef
def assert_destination_writable!
if (File.exists?(destination) && !File.writable?(destination)) or !File.writable?(File.dirname(destination))
- raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination} - check permissions?"
+ abs_path = File.expand_path(destination)
+ raise Chef::Exceptions::CannotWritePrivateKey, "I can't write your private key to #{abs_path} - check permissions?"
end
end
diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb
index b21b838d72..4c559542f1 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -196,6 +196,7 @@ class Chef::Application::Apply < Chef::Application
ensure
@recipe_fh.close
end
+ Chef::Platform::Rebooter.reboot_if_needed!(runner)
end
def run_application
diff --git a/lib/chef/digester.rb b/lib/chef/digester.rb
index 75c4e76859..f2b496b785 100644
--- a/lib/chef/digester.rb
+++ b/lib/chef/digester.rb
@@ -38,7 +38,11 @@ class Chef
end
def generate_checksum(file)
- checksum_file(file, OpenSSL::Digest::SHA256.new)
+ if file.is_a?(StringIO)
+ checksum_io(file, OpenSSL::Digest::SHA256.new)
+ else
+ checksum_file(file, OpenSSL::Digest::SHA256.new)
+ end
end
def self.generate_md5_checksum_for_file(*args)
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 6e7ff2e24a..855c86d9cc 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -74,6 +74,11 @@ class Chef
class InvalidPrivateKey < ArgumentError; end
class MissingKeyAttribute < ArgumentError; end
class KeyCommandInputError < ArgumentError; end
+ class BootstrapCommandInputError < ArgumentError
+ def initialize
+ super "You cannot pass both --json-attributes and --json-attribute-file. Please pass one or none."
+ end
+ end
class InvalidKeyArgument < ArgumentError; end
class InvalidKeyAttribute < ArgumentError; end
class InvalidUserAttribute < ArgumentError; end
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 93236225a2..8502ccb8eb 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -42,7 +42,7 @@ class Chef
Chef::Knife::Ssh.load_deps
end
- banner "knife bootstrap FQDN (options)"
+ banner "knife bootstrap [SSH_USER@]FQDN (options)"
option :ssh_user,
:short => "-x USERNAME",
@@ -122,6 +122,11 @@ class Chef
:description => "Execute the bootstrap via sudo",
:boolean => true
+ option :preserve_home,
+ :long => "--sudo-preserve-home",
+ :description => "Preserve non-root user HOME environment variable with sudo",
+ :boolean => true
+
option :use_sudo_password,
:long => "--use-sudo-password",
:description => "Execute the bootstrap via sudo with password",
@@ -164,7 +169,13 @@ class Chef
:long => "--json-attributes",
:description => "A JSON string to be added to the first run of chef-client",
:proc => lambda { |o| Chef::JSONCompat.parse(o) },
- :default => {}
+ :default => nil
+
+ option :first_boot_attributes_from_file,
+ :long => "--json-attribute-file FILE",
+ :description => "A JSON file to be used to the first run of chef-client",
+ :proc => lambda { |o| Chef::JSONCompat.parse(File.read(o)) },
+ :default => nil
option :host_key_verify,
:long => "--[no-]host-key-verify",
@@ -256,13 +267,25 @@ class Chef
"chef-full"
end
+ def host_descriptor
+ Array(@name_args).first
+ end
+
# The server_name is the DNS or IP we are going to connect to, it is not necessarily
# the node name, the fqdn, or the hostname of the server. This is a public API hook
# which knife plugins use or inherit and override.
#
# @return [String] The DNS or IP that bootstrap will connect to
def server_name
- Array(@name_args).first
+ if host_descriptor
+ @server_name ||= host_descriptor.split('@').reverse[0]
+ end
+ end
+
+ def user_name
+ if host_descriptor
+ @user_name ||= host_descriptor.split('@').reverse[1]
+ end
end
def bootstrap_template
@@ -317,13 +340,22 @@ class Chef
)
end
+ def first_boot_attributes
+ @config[:first_boot_attributes] || @config[:first_boot_attributes_from_file] || {}
+ end
+
def render_template
+ @config[:first_boot_attributes] = first_boot_attributes
template_file = find_template
template = IO.read(template_file).chomp
Erubis::Eruby.new(template).evaluate(bootstrap_context)
end
def run
+ if @config[:first_boot_attributes] && @config[:first_boot_attributes_from_file]
+ raise Chef::Exceptions::BootstrapCommandInputError
+ end
+
validate_name_args!
validate_options!
@@ -358,7 +390,7 @@ class Chef
if config[:ssh_password]
raise
else
- ui.info("Failed to authenticate #{config[:ssh_user]} - trying password auth")
+ ui.info("Failed to authenticate #{knife_ssh.config[:ssh_user]} - trying password auth")
knife_ssh_with_password_auth.run
end
end
@@ -389,7 +421,7 @@ class Chef
ssh = Chef::Knife::Ssh.new
ssh.ui = ui
ssh.name_args = [ server_name, ssh_command ]
- ssh.config[:ssh_user] = config[:ssh_user]
+ ssh.config[:ssh_user] = user_name || config[:ssh_user]
ssh.config[:ssh_password] = config[:ssh_password]
ssh.config[:ssh_port] = config[:ssh_port]
ssh.config[:ssh_gateway] = config[:ssh_gateway]
@@ -412,7 +444,8 @@ class Chef
command = render_template
if config[:use_sudo]
- command = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -SH #{command}" : "sudo -H #{command}"
+ sudo_prefix = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -S " : "sudo "
+ command = config[:preserve_home] ? "#{sudo_prefix} #{command}" : "#{sudo_prefix} -H #{command}"
end
command
diff --git a/lib/chef/knife/cookbook_site_install.rb b/lib/chef/knife/cookbook_site_install.rb
index aee8b7fa94..cc68fe7897 100644
--- a/lib/chef/knife/cookbook_site_install.rb
+++ b/lib/chef/knife/cookbook_site_install.rb
@@ -142,7 +142,11 @@ class Chef
def extract_cookbook(upstream_file, version)
ui.info("Uncompressing #{@cookbook_name} version #{version}.")
# FIXME: Detect if we have the bad tar from git on Windows: https://github.com/opscode/chef/issues/1753
- shell_out!("tar zxvf #{convert_path upstream_file}", :cwd => @install_path)
+ extract_command="tar zxvf \"#{convert_path upstream_file}\""
+ if Chef::Platform.windows?
+ extract_command << " --force-local"
+ end
+ shell_out!(extract_command, :cwd => @install_path)
end
def clear_existing_files(cookbook_path)
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index d210b9418f..8613a50cb4 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -40,7 +40,7 @@ class Chef
end
def bootstrap_environment
- @chef_config[:environment]
+ @config[:environment]
end
def validation_key
diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb
index 996f40c91d..89a9608c60 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -111,6 +111,12 @@ class Chef
:boolean => true,
:proc => Proc.new { :raise }
+ option :tmux_split,
+ :long => "--tmux-split",
+ :description => "Split tmux window.",
+ :boolean => true,
+ :default => false
+
def session
config[:on_error] ||= :skip
ssh_error_handler = Proc.new do |server|
@@ -404,7 +410,11 @@ class Chef
new_window_cmds = lambda do
if session.servers_for.size > 1
[""] + session.servers_for[1..-1].map do |server|
- "new-window -a -n '#{server.host}' #{ssh_dest.call(server)}"
+ if config[:tmux_split]
+ "split-window #{ssh_dest.call(server)}; tmux select-layout tiled"
+ else
+ "new-window -a -n '#{server.host}' #{ssh_dest.call(server)}"
+ end
end
else
[]
diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb
index 95f2c724ff..1a61b035cb 100644
--- a/lib/chef/knife/status.rb
+++ b/lib/chef/knife/status.rb
@@ -44,7 +44,11 @@ class Chef
option :hide_healthy,
:short => "-H",
:long => "--hide-healthy",
- :description => "Hide nodes that have run chef in the last hour"
+ :description => "Hide nodes that have run chef in the last hour. [DEPRECATED] Use --hide-by-mins MINS instead"
+
+ option :hide_by_mins,
+ :long => "--hide-by-mins MINS",
+ :description => "Hide nodes that have run chef in the last MINS minutes"
def append_to_query(term)
@query << " AND " unless @query.empty?
@@ -68,12 +72,21 @@ class Chef
append_to_query("chef_environment:#{config[:environment]}") if config[:environment]
if config[:hide_healthy]
+ ui.warn("-H / --hide-healthy is deprecated. Use --hide-by-mins MINS instead")
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}]"
end
+ if config[:hide_by_mins]
+ hidemins = config[:hide_by_mins].to_i
+ 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}]"
+ end
+
@query = @query.empty? ? "*:*" : @query
all_nodes = []
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index ad065cc02b..83ec7e2550 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -647,6 +647,14 @@ class Chef
"node[#{name}]"
end
+ def ==(other)
+ if other.kind_of?(self.class)
+ self.name == other.name
+ else
+ false
+ end
+ end
+
def <=>(other_node)
self.name <=> other_node.name
end
diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb
index 77a0410593..c59200e717 100644
--- a/lib/chef/provider/deploy.rb
+++ b/lib/chef/provider/deploy.rb
@@ -276,7 +276,7 @@ class Chef
def enforce_ownership
converge_by("force ownership of #{@new_resource.deploy_to} to #{@new_resource.group}:#{@new_resource.user}") do
- FileUtils.chown_R(@new_resource.user, @new_resource.group, @new_resource.deploy_to)
+ FileUtils.chown_R(@new_resource.user, @new_resource.group, @new_resource.deploy_to, :force => true)
Chef::Log.info("#{@new_resource} set user to #{@new_resource.user}") if @new_resource.user
Chef::Log.info("#{@new_resource} set group to #{@new_resource.group}") if @new_resource.group
end
diff --git a/lib/chef/provider/execute.rb b/lib/chef/provider/execute.rb
index c3dd3b4ee1..30de0d3b9e 100644
--- a/lib/chef/provider/execute.rb
+++ b/lib/chef/provider/execute.rb
@@ -58,7 +58,16 @@ class Chef
end
converge_by("execute #{description}") do
- result = shell_out!(command, opts)
+ begin
+ shell_out!(command, opts)
+ rescue Mixlib::ShellOut::ShellCommandFailed
+ if sensitive?
+ raise Mixlib::ShellOut::ShellCommandFailed,
+ "Command execution failed. STDOUT/STDERR suppressed for sensitive resource"
+ else
+ raise
+ end
+ end
Chef::Log.info("#{new_resource} ran successfully")
end
end
diff --git a/lib/chef/provider/group.rb b/lib/chef/provider/group.rb
index a802758dce..a1cf92058d 100644
--- a/lib/chef/provider/group.rb
+++ b/lib/chef/provider/group.rb
@@ -125,7 +125,7 @@ class Chef
def action_create
case @group_exists
when false
- converge_by("create #{@new_resource.group_name}") do
+ converge_by("create group #{@new_resource.group_name}") do
create_group
Chef::Log.info("#{@new_resource} created")
end
diff --git a/lib/chef/resource/registry_key.rb b/lib/chef/resource/registry_key.rb
index d2e5c4b94c..f1bf7954ce 100644
--- a/lib/chef/resource/registry_key.rb
+++ b/lib/chef/resource/registry_key.rb
@@ -125,7 +125,7 @@ class Chef
scrubbed_value = value.dup
if needs_checksum?(scrubbed_value)
data_io = StringIO.new(scrubbed_value[:data].to_s)
- scrubbed_value[:data] = Chef::Digester.instance.generate_md5_checksum(data_io)
+ scrubbed_value[:data] = Chef::Digester.instance.generate_checksum(data_io)
end
scrubbed << scrubbed_value
end
diff --git a/lib/chef/resource/resource_notification.rb b/lib/chef/resource/resource_notification.rb
index a27ed961c7..4fd61ad1f8 100644
--- a/lib/chef/resource/resource_notification.rb
+++ b/lib/chef/resource/resource_notification.rb
@@ -20,7 +20,15 @@ require 'chef/resource'
class Chef
class Resource
- class Notification < Struct.new(:resource, :action, :notifying_resource)
+ class Notification
+
+ attr_accessor :resource, :action, :notifying_resource
+
+ def initialize(resource, action, notifying_resource)
+ @resource = resource
+ @action = action
+ @notifying_resource = notifying_resource
+ end
def duplicates?(other_notification)
unless other_notification.respond_to?(:resource) && other_notification.respond_to?(:action)
@@ -104,6 +112,11 @@ is defined near #{resource.source_line}
raise err
end
+ def ==(other)
+ return false unless other.is_a?(self.class)
+ other.resource == resource && other.action == action && other.notifying_resource == notifying_resource
+ end
+
end
end
end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 48aae3e61b..342c1878f1 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -235,12 +235,39 @@ describe Chef::Knife::Bootstrap do
expect(knife.render_template).to eq('{"run_list":["role[base]","recipe[cupcakes]"]}')
end
- it "should have foo => {bar => baz} in the first_boot" do
- knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
- knife.merge_configs
- expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
- actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
- expect(actual_hash).to eq(expected_hash)
+ context "with bootstrap_attribute options" do
+ let(:jsonfile) {
+ file = Tempfile.new (['node', '.json'])
+ File.open(file.path, "w") {|f| f.puts '{"foo":{"bar":"baz"}}' }
+ file
+ }
+
+ it "should have foo => {bar => baz} in the first_boot from cli" do
+ knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
+ knife.merge_configs
+ expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
+ actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
+ expect(actual_hash).to eq(expected_hash)
+ end
+
+ it "should have foo => {bar => baz} in the first_boot from file" do
+ knife.parse_options(["--json-attribute-file", jsonfile.path])
+ knife.merge_configs
+ expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
+ actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
+ expect(actual_hash).to eq(expected_hash)
+ jsonfile.close
+ end
+
+ context "when --json-attributes and --json-attribute-file were both passed" do
+ it "raises a Chef::Exceptions::BootstrapCommandInputError with the proper error message" do
+ knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
+ knife.parse_options(["--json-attribute-file", jsonfile.path])
+ knife.merge_configs
+ expect{ knife.run }.to raise_error(Chef::Exceptions::BootstrapCommandInputError)
+ jsonfile.close
+ end
+ end
end
end
diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb
index 0433ef9983..4d69d6300a 100644
--- a/spec/unit/knife/core/bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/bootstrap_context_spec.rb
@@ -91,7 +91,7 @@ EXPECTED
end
describe "when bootstrapping into a specific environment" do
- let(:chef_config){ {:environment => "prodtastic"} }
+ let(:config){ {:environment => "prodtastic"} }
it "starts chef in the configured environment" do
expect(bootstrap_context.start_chef).to eq('chef-client -j /etc/chef/first-boot.json -E prodtastic')
end
diff --git a/spec/unit/knife/status_spec.rb b/spec/unit/knife/status_spec.rb
index ee44f3b3fd..11728a6f9b 100644
--- a/spec/unit/knife/status_spec.rb
+++ b/spec/unit/knife/status_spec.rb
@@ -44,9 +44,9 @@ describe Chef::Knife::Status do
@knife.run
end
- it "should filter healthy nodes" do
- @knife.config[:hide_healthy] = true
- expect(@query).to receive(:search).with(:node, "NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ it "should filter by nodes older than some mins" do
+ @knife.config[:hide_by_mins] = 59
+ expect(@query).to receive(:search).with(:node, "NOT ohai_time:[1428569880 TO 1428573420]", opts)
@knife.run
end
@@ -56,10 +56,10 @@ describe Chef::Knife::Status do
@knife.run
end
- it "should filter by environment and health" do
+ it "should filter by environment and nodes older than some mins" do
@knife.config[:environment] = "production"
- @knife.config[:hide_healthy] = true
- expect(@query).to receive(:search).with(:node, "chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.config[:hide_by_mins] = 59
+ expect(@query).to receive(:search).with(:node, "chef_environment:production NOT ohai_time:[1428569880 TO 1428573420]", opts)
@knife.run
end
@@ -79,22 +79,22 @@ describe Chef::Knife::Status do
@knife.run
end
- it "should filter healthy nodes" do
- @knife.config[:hide_healthy] = true
- expect(@query).to receive(:search).with(:node, "name:my_custom_name NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ it "should filter by nodes older than some mins with nodename specified" do
+ @knife.config[:hide_by_mins] = 59
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name NOT ohai_time:[1428569880 TO 1428573420]", opts)
@knife.run
end
- it "should filter by environment" do
+ it "should filter by environment with nodename specified" do
@knife.config[:environment] = "production"
expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production", opts)
@knife.run
end
- it "should filter by environment and health" do
+ it "should filter by environment and nodes older than some mins with nodename specified" do
@knife.config[:environment] = "production"
- @knife.config[:hide_healthy] = true
- expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.config[:hide_by_mins] = 59
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production NOT ohai_time:[1428569880 TO 1428573420]", opts)
@knife.run
end
end
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 5f3bed2833..17e085a465 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -42,6 +42,14 @@ describe Chef::Node do
expect([n3, n1, n2].sort).to eq([n1, n2, n3])
end
+ it "should share identity only with others of the same name" do
+ n1 = Chef::Node.build('foo')
+ n2 = Chef::Node.build('foo')
+ n3 = Chef::Node.build('bar')
+ expect(n1).to eq(n2)
+ expect(n1).not_to eq(n3)
+ end
+
describe "when the node does not exist on the server" do
before do
response = OpenStruct.new(:code => '404')
diff --git a/spec/unit/provider/deploy_spec.rb b/spec/unit/provider/deploy_spec.rb
index e6a7125e32..adcb9431eb 100644
--- a/spec/unit/provider/deploy_spec.rb
+++ b/spec/unit/provider/deploy_spec.rb
@@ -356,7 +356,7 @@ describe Chef::Provider::Deploy do
it "chowns the whole release dir to user and group specified in the resource" do
@resource.user "foo"
@resource.group "bar"
- expect(FileUtils).to receive(:chown_R).with("foo", "bar", "/my/deploy/dir")
+ expect(FileUtils).to receive(:chown_R).with("foo", "bar", "/my/deploy/dir", { :force => true })
@provider.enforce_ownership
end
diff --git a/spec/unit/provider/execute_spec.rb b/spec/unit/provider/execute_spec.rb
index 1274203ce3..e7607d9417 100644
--- a/spec/unit/provider/execute_spec.rb
+++ b/spec/unit/provider/execute_spec.rb
@@ -172,5 +172,14 @@ describe Chef::Provider::Execute do
provider.run_action(:run)
expect(new_resource).to be_updated
end
+
+ it "should not include stdout/stderr in failure exception for sensitive resource" do
+ opts.delete(:live_stream)
+ new_resource.sensitive true
+ expect(provider).to receive(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ expect do
+ provider.run_action(:run)
+ end.to raise_error(Mixlib::ShellOut::ShellCommandFailed, /suppressed for sensitive resource/)
+ end
end
end
diff --git a/spec/unit/resource/registry_key_spec.rb b/spec/unit/resource/registry_key_spec.rb
index 2e2811d026..2d82f1a51c 100644
--- a/spec/unit/resource/registry_key_spec.rb
+++ b/spec/unit/resource/registry_key_spec.rb
@@ -91,7 +91,7 @@ describe Chef::Resource::RegistryKey, "values" do
it "should return checksummed data if the type is unsafe" do
@resource.values( { :name => 'poosh', :type => :binary, :data => 255.chr * 1 })
- expect(@resource.values).to eql([ { :name => 'poosh', :type => :binary, :data => "00594fd4f42ba43fc1ca0427a0576295" } ])
+ expect(@resource.values).to eql([ { :name => 'poosh', :type => :binary, :data => 'a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89' } ])
end
it "should throw an exception if the name field is missing" do
@@ -194,6 +194,6 @@ describe Chef::Resource::RegistryKey, "state" do
it "should return scrubbed values" do
@resource.values([ { :name => 'poosh', :type => :binary, :data => 255.chr * 1 } ])
- expect(@resource.state).to eql( { :values => [{ :name => 'poosh', :type => :binary, :data => "00594fd4f42ba43fc1ca0427a0576295" }] } )
+ expect(@resource.state).to eql( { :values => [{ :name => 'poosh', :type => :binary, :data => 'a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89'}] } )
end
end
diff --git a/spec/unit/resource/resource_notification_spec.rb b/spec/unit/resource/resource_notification_spec.rb
index 7f6b124d4d..024b6f93f7 100644
--- a/spec/unit/resource/resource_notification_spec.rb
+++ b/spec/unit/resource/resource_notification_spec.rb
@@ -19,149 +19,148 @@ require 'spec_helper'
require 'chef/resource/resource_notification'
describe Chef::Resource::Notification do
- before do
- @notification = Chef::Resource::Notification.new(:service_apache, :restart, :template_httpd_conf)
- end
+
+ let(:notification) { Chef::Resource::Notification.new(:service_apache, :restart, :template_httpd_conf) }
it "has a resource to be notified" do
- expect(@notification.resource).to eq(:service_apache)
+ expect(notification.resource).to eq(:service_apache)
end
it "has an action to take on the service" do
- expect(@notification.action).to eq(:restart)
+ expect(notification.action).to eq(:restart)
end
it "has a notifying resource" do
- expect(@notification.notifying_resource).to eq(:template_httpd_conf)
+ expect(notification.notifying_resource).to eq(:template_httpd_conf)
end
it "is a duplicate of another notification with the same target resource and action" do
other = Chef::Resource::Notification.new(:service_apache, :restart, :sync_web_app_code)
- expect(@notification.duplicates?(other)).to be_truthy
+ expect(notification.duplicates?(other)).to be_truthy
end
it "is not a duplicate of another notification if the actions differ" do
other = Chef::Resource::Notification.new(:service_apache, :enable, :install_apache)
- expect(@notification.duplicates?(other)).to be_falsey
+ expect(notification.duplicates?(other)).to be_falsey
end
it "is not a duplicate of another notification if the target resources differ" do
other = Chef::Resource::Notification.new(:service_sshd, :restart, :template_httpd_conf)
- expect(@notification.duplicates?(other)).to be_falsey
+ expect(notification.duplicates?(other)).to be_falsey
end
it "raises an ArgumentError if you try to check a non-ducktype object for duplication" do
- expect {@notification.duplicates?(:not_a_notification)}.to raise_error(ArgumentError)
+ expect {notification.duplicates?(:not_a_notification)}.to raise_error(ArgumentError)
end
it "takes no action to resolve a resource reference that doesn't need to be resolved" do
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
- @notification.resource = @keyboard_cat
+ notification.resource = @keyboard_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
- @notification.notifying_resource = @long_cat
+ notification.notifying_resource = @long_cat
@resource_collection = Chef::ResourceCollection.new
# would raise an error since the resource is not in the collection
- @notification.resolve_resource_reference(@resource_collection)
- expect(@notification.resource).to eq(@keyboard_cat)
+ notification.resolve_resource_reference(@resource_collection)
+ expect(notification.resource).to eq(@keyboard_cat)
end
it "resolves a lazy reference to a resource" do
- @notification.resource = {:cat => "keyboard_cat"}
+ notification.resource = {:cat => "keyboard_cat"}
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @keyboard_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
- @notification.notifying_resource = @long_cat
- @notification.resolve_resource_reference(@resource_collection)
- expect(@notification.resource).to eq(@keyboard_cat)
+ notification.notifying_resource = @long_cat
+ notification.resolve_resource_reference(@resource_collection)
+ expect(notification.resource).to eq(@keyboard_cat)
end
it "resolves a lazy reference to its notifying resource" do
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
- @notification.resource = @keyboard_cat
- @notification.notifying_resource = {:cat => "long_cat"}
+ notification.resource = @keyboard_cat
+ notification.notifying_resource = {:cat => "long_cat"}
@long_cat = Chef::Resource::Cat.new("long_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @long_cat
- @notification.resolve_resource_reference(@resource_collection)
- expect(@notification.notifying_resource).to eq(@long_cat)
+ notification.resolve_resource_reference(@resource_collection)
+ expect(notification.notifying_resource).to eq(@long_cat)
end
it "resolves lazy references to both its resource and its notifying resource" do
- @notification.resource = {:cat => "keyboard_cat"}
+ notification.resource = {:cat => "keyboard_cat"}
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @keyboard_cat
- @notification.notifying_resource = {:cat => "long_cat"}
+ notification.notifying_resource = {:cat => "long_cat"}
@long_cat = Chef::Resource::Cat.new("long_cat")
@resource_collection << @long_cat
- @notification.resolve_resource_reference(@resource_collection)
- expect(@notification.resource).to eq(@keyboard_cat)
- expect(@notification.notifying_resource).to eq(@long_cat)
+ notification.resolve_resource_reference(@resource_collection)
+ expect(notification.resource).to eq(@keyboard_cat)
+ expect(notification.notifying_resource).to eq(@long_cat)
end
it "raises a RuntimeError if you try to reference multiple resources" do
- @notification.resource = {:cat => ["keyboard_cat", "cheez_cat"]}
+ notification.resource = {:cat => ["keyboard_cat", "cheez_cat"]}
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@cheez_cat = Chef::Resource::Cat.new("cheez_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @keyboard_cat
@resource_collection << @cheez_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
- @notification.notifying_resource = @long_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
+ notification.notifying_resource = @long_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if you try to reference multiple notifying resources" do
- @notification.notifying_resource = {:cat => ["long_cat", "cheez_cat"]}
+ notification.notifying_resource = {:cat => ["long_cat", "cheez_cat"]}
@long_cat = Chef::Resource::Cat.new("long_cat")
@cheez_cat = Chef::Resource::Cat.new("cheez_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @long_cat
@resource_collection << @cheez_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
- @notification.resource = @keyboard_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
+ notification.resource = @keyboard_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if it can't find a resource in the resource collection when resolving a lazy reference" do
- @notification.resource = {:cat => "keyboard_cat"}
+ notification.resource = {:cat => "keyboard_cat"}
@cheez_cat = Chef::Resource::Cat.new("cheez_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @cheez_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
- @notification.notifying_resource = @long_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
+ notification.notifying_resource = @long_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if it can't find a notifying resource in the resource collection when resolving a lazy reference" do
- @notification.notifying_resource = {:cat => "long_cat"}
+ notification.notifying_resource = {:cat => "long_cat"}
@cheez_cat = Chef::Resource::Cat.new("cheez_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @cheez_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
- @notification.resource = @keyboard_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
+ notification.resource = @keyboard_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises an ArgumentError if improper syntax is used in the lazy reference to its resource" do
- @notification.resource = "cat => keyboard_cat"
+ notification.resource = "cat => keyboard_cat"
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @keyboard_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
- @notification.notifying_resource = @long_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
+ notification.notifying_resource = @long_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
end
it "raises an ArgumentError if improper syntax is used in the lazy reference to its notifying resource" do
- @notification.notifying_resource = "cat => long_cat"
+ notification.notifying_resource = "cat => long_cat"
@long_cat = Chef::Resource::Cat.new("long_cat")
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @long_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
- @notification.resource = @keyboard_cat
- expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
+ notification.resource = @keyboard_cat
+ expect {notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
end
# Create test to resolve lazy references to both notifying resource and dest. resource
diff --git a/spec/unit/rest_spec.rb b/spec/unit/rest_spec.rb
index 3b04981610..3eee997c50 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -69,8 +69,8 @@ describe Chef::REST do
rest
end
- let(:standard_read_headers) {{"Accept"=>"application/json", "Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "X-REMOTE-REQUEST-ID"=>request_id, 'X-Ops-Server-API-Version' => Chef::HTTP::Authenticator::DEFAULT_SERVER_API_VERSION}}
- let(:standard_write_headers) {{"Accept"=>"application/json", "Content-Type"=>"application/json", "Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "X-REMOTE-REQUEST-ID"=>request_id, 'X-Ops-Server-API-Version' => Chef::HTTP::Authenticator::DEFAULT_SERVER_API_VERSION}}
+ let(:standard_read_headers) {{"Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "X-REMOTE-REQUEST-ID"=>request_id, 'X-Ops-Server-API-Version' => Chef::HTTP::Authenticator::DEFAULT_SERVER_API_VERSION}}
+ let(:standard_write_headers) {{"Accept"=>"application/json", "Content-Type"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "X-REMOTE-REQUEST-ID"=>request_id, 'X-Ops-Server-API-Version' => Chef::HTTP::Authenticator::DEFAULT_SERVER_API_VERSION}}
before(:each) do
Chef::Log.init(log_stringio)