summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wrock <matt@mattwrock.com>2020-10-30 21:36:27 +0000
committerGitHub <noreply@github.com>2020-10-30 21:36:27 +0000
commit8248fa5b5542840bc6adbeaf32445e008397dc55 (patch)
tree1196f8804fb746d8c5dca2270c786da086770fad
parent4b56eedf7c805d4ba649bd514cad8f16c0d892d2 (diff)
parent31e13be0222e96d3f9b194b2530d6a0a1892a117 (diff)
downloadchef-8248fa5b5542840bc6adbeaf32445e008397dc55.tar.gz
Merge pull request #10545 from chef/out_to_exec
Improve Windows resource performance by converting powershell_out usage to powershell_exec
-rw-r--r--.expeditor/verify.pipeline.yml1
-rw-r--r--lib/chef/powershell.rb12
-rw-r--r--lib/chef/provider/package/chocolatey.rb8
-rw-r--r--lib/chef/resource/hostname.rb2
-rw-r--r--lib/chef/resource/powershell_package_source.rb37
-rw-r--r--lib/chef/resource/windows_ad_join.rb18
-rw-r--r--lib/chef/resource/windows_certificate.rb10
-rw-r--r--lib/chef/resource/windows_dfs_server.rb11
-rw-r--r--lib/chef/resource/windows_firewall_profile.rb19
-rw-r--r--lib/chef/resource/windows_firewall_rule.rb20
-rw-r--r--lib/chef/resource/windows_security_policy.rb10
-rw-r--r--lib/chef/resource/windows_share.rb36
-rw-r--r--lib/chef/resource/windows_workgroup.rb8
-rw-r--r--spec/functional/resource/chocolatey_package_spec.rb6
-rw-r--r--spec/functional/resource/dsc_script_spec.rb6
-rw-r--r--spec/functional/resource/powershell_package_source_spec.rb103
-rw-r--r--spec/functional/resource/windows_certificate_spec.rb16
-rw-r--r--spec/functional/resource/windows_firewall_rule_spec.rb93
-rw-r--r--spec/functional/resource/windows_share_spec.rb103
-rw-r--r--spec/support/platform_helpers.rb10
-rw-r--r--spec/unit/provider/package/chocolatey_spec.rb3
-rw-r--r--spec/unit/resource/powershell_package_source_spec.rb40
22 files changed, 440 insertions, 132 deletions
diff --git a/.expeditor/verify.pipeline.yml b/.expeditor/verify.pipeline.yml
index 3f6f45be6e..5c58574cb3 100644
--- a/.expeditor/verify.pipeline.yml
+++ b/.expeditor/verify.pipeline.yml
@@ -620,6 +620,7 @@ steps:
- label: ":habicat: Windows plan"
commands:
- ./scripts/ci/verify-plan.ps1
+ timeout_in_minutes: 60
expeditor:
executor:
windows:
diff --git a/lib/chef/powershell.rb b/lib/chef/powershell.rb
index 5063e599c6..4800708dfc 100644
--- a/lib/chef/powershell.rb
+++ b/lib/chef/powershell.rb
@@ -34,8 +34,6 @@ class Chef
# @param script [String] script to run
# @return [Object] output
def initialize(script)
- raise "Chef::PowerShell can only be used on the Windows platform." unless RUBY_PLATFORM.match?(/mswin|mingw32|windows/)
-
@dll ||= "Chef.PowerShell.Wrapper.dll"
exec(script)
end
@@ -65,7 +63,15 @@ class Chef
def exec(script)
FFI.ffi_lib @dll
FFI.attach_function :execute_powershell, :ExecuteScript, [:string], :pointer
- execution = FFI.execute_powershell(script).read_utf16string
+ # This is a temporary fix for running in a Habitat environment
+ # In habitat we set CHEF_POWERSHELL_BIN so that .Net resolves our
+ # managed shim assembly from the correct location.
+ # It seems that that is preventing .Net from successfully loading GAC assemblies
+ # and can break all sorts of edge (and not so edge) scenarios. Once we are actually
+ # inside the powershell run space, we know our shim was loaded and can unset
+ # CHEF_POWERSHELL_BIN which will bypass our custom resolver logic. The real fix is
+ # to fix our resolver. Oh and OH MY GOD this was a pain to track down.
+ execution = FFI.execute_powershell("$ENV:CHEF_POWERSHELL_BIN=$NULL;#{script}").read_utf16string
hashed_outcome = Chef::JSONCompat.parse(execution)
@result = Chef::JSONCompat.parse(hashed_outcome["result"])
@errors = hashed_outcome["errors"]
diff --git a/lib/chef/provider/package/chocolatey.rb b/lib/chef/provider/package/chocolatey.rb
index 498a98f2d0..156568e584 100644
--- a/lib/chef/provider/package/chocolatey.rb
+++ b/lib/chef/provider/package/chocolatey.rb
@@ -151,7 +151,7 @@ class Chef
@choco_exe ||= begin
# if this check is in #define_resource_requirements, it won't get
# run before choco.exe gets called from #load_current_resource.
- exe_path = ::File.join(choco_install_path.to_s, "bin", "choco.exe")
+ exe_path = ::File.join(choco_install_path, "bin", "choco.exe")
raise Chef::Exceptions::MissingLibrary, CHOCO_MISSING_MSG unless ::File.exist?(exe_path)
exe_path
@@ -160,9 +160,9 @@ class Chef
# lets us mock out an incorrect value for testing.
def choco_install_path
- @choco_install_path ||= powershell_out!(
- PATHFINDING_POWERSHELL_COMMAND
- ).stdout.chomp
+ result = powershell_exec!(PATHFINDING_POWERSHELL_COMMAND).result
+ result = "" if result.empty?
+ result
end
# Helper to dispatch a choco command through shell_out using the timeout
diff --git a/lib/chef/resource/hostname.rb b/lib/chef/resource/hostname.rb
index 07a71864c2..27903e5807 100644
--- a/lib/chef/resource/hostname.rb
+++ b/lib/chef/resource/hostname.rb
@@ -240,7 +240,7 @@ class Chef
unless Socket.gethostbyname(Socket.gethostname).first == new_resource.hostname
converge_by "set hostname to #{new_resource.hostname}" do
- powershell_out! <<~EOH
+ powershell_exec! <<~EOH
$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$sysInfo.Rename("#{new_resource.hostname}")
EOH
diff --git a/lib/chef/resource/powershell_package_source.rb b/lib/chef/resource/powershell_package_source.rb
index e17c23abe2..066efc6a72 100644
--- a/lib/chef/resource/powershell_package_source.rb
+++ b/lib/chef/resource/powershell_package_source.rb
@@ -16,7 +16,6 @@
#
require_relative "../resource"
-require_relative "../json_compat"
class Chef
class Resource
@@ -57,11 +56,11 @@ class Chef
load_current_value do
cmd = load_resource_state_script(source_name)
- repo = powershell_out!(cmd)
- if repo.stdout.empty?
+ repo = powershell_exec!(cmd)
+ if repo.result.empty?
current_value_does_not_exist!
else
- status = Chef::JSONCompat.from_json(repo.stdout)
+ status = repo.result
end
url status["url"]
trusted status["trusted"]
@@ -78,28 +77,28 @@ class Chef
if package_source_exists?
converge_if_changed :url, :trusted, :publish_location, :script_source_location, :script_publish_location do
update_cmd = build_ps_repository_command("Set", new_resource)
- res = powershell_out(update_cmd)
- raise "Failed to update #{new_resource.source_name}: #{res.stderr}" unless res.stderr.empty?
+ res = powershell_exec(update_cmd)
+ raise "Failed to update #{new_resource.source_name}: #{res.errors}" if res.error?
end
else
converge_by("register source: #{new_resource.source_name}") do
register_cmd = build_ps_repository_command("Register", new_resource)
- res = powershell_out(register_cmd)
- raise "Failed to register #{new_resource.source_name}: #{res.stderr}" unless res.stderr.empty?
+ res = powershell_exec(register_cmd)
+ raise "Failed to register #{new_resource.source_name}: #{res.errors}" if res.error?
end
end
else
if package_source_exists?
converge_if_changed :url, :trusted, :provider_name do
update_cmd = build_package_source_command("Set", new_resource)
- res = powershell_out(update_cmd)
- raise "Failed to update #{new_resource.source_name}: #{res.stderr}" unless res.stderr.empty?
+ res = powershell_exec(update_cmd)
+ raise "Failed to update #{new_resource.source_name}: #{res.errors}" if res.error?
end
else
converge_by("register source: #{new_resource.source_name}") do
register_cmd = build_package_source_command("Register", new_resource)
- res = powershell_out(register_cmd)
- raise "Failed to register #{new_resource.source_name}: #{res.stderr}" unless res.stderr.empty?
+ res = powershell_exec(register_cmd)
+ raise "Failed to register #{new_resource.source_name}: #{res.errors}" if res.error?
end
end
end
@@ -110,16 +109,16 @@ class Chef
if package_source_exists?
unregister_cmd = "Get-PackageSource -Name '#{new_resource.source_name}' | Unregister-PackageSource"
converge_by("unregister source: #{new_resource.source_name}") do
- res = powershell_out(unregister_cmd)
- raise "Failed to unregister #{new_resource.source_name}: #{res.stderr}" unless res.stderr.empty?
+ res = powershell_exec(unregister_cmd)
+ raise "Failed to unregister #{new_resource.source_name}: #{res.errors}" if res.error?
end
end
end
action_class do
def package_source_exists?
- cmd = powershell_out!("(Get-PackageSource -Name '#{new_resource.source_name}' -WarningAction SilentlyContinue).Name")
- cmd.stdout.downcase.strip == new_resource.source_name.downcase
+ cmd = powershell_exec!("(Get-PackageSource -Name '#{new_resource.source_name}' -ErrorAction SilentlyContinue).Name")
+ !cmd.result.empty? && cmd.result.to_s.downcase.strip == new_resource.source_name.downcase
end
def psrepository_cmdlet_appropriate?
@@ -133,6 +132,7 @@ class Chef
cmd << " -PublishLocation '#{new_resource.publish_location}'" if new_resource.publish_location
cmd << " -ScriptSourceLocation '#{new_resource.script_source_location}'" if new_resource.script_source_location
cmd << " -ScriptPublishLocation '#{new_resource.script_publish_location}'" if new_resource.script_publish_location
+ cmd << " | Out-Null"
cmd
end
@@ -141,6 +141,7 @@ class Chef
cmd << " -Location '#{new_resource.url}'" if new_resource.url
cmd << " -Trusted:#{new_resource.trusted ? "$true" : "$false"}"
cmd << " -ProviderName '#{new_resource.provider_name}'" if new_resource.provider_name
+ cmd << " | Out-Null"
cmd
end
end
@@ -157,11 +158,11 @@ class Chef
if ((Get-PackageSource -Name '#{name}').ProviderName -eq 'PowerShellGet') {
(Get-PSRepository -Name '#{name}') | Select @{n='source_name';e={$_.Name}}, @{n='url';e={$_.SourceLocation}},
@{n='trusted';e={$_.Trusted}}, @{n='provider_name';e={$_.PackageManagementProvider}}, @{n='publish_location';e={$_.PublishLocation}},
- @{n='script_source_location';e={$_.ScriptSourceLocation}}, @{n='script_publish_location';e={$_.ScriptPublishLocation}} | ConvertTo-Json
+ @{n='script_source_location';e={$_.ScriptSourceLocation}}, @{n='script_publish_location';e={$_.ScriptPublishLocation}}
}
else {
(Get-PackageSource -Name '#{name}') | Select @{n='source_name';e={$_.Name}}, @{n='url';e={$_.Location}},
- @{n='provider_name';e={$_.ProviderName}}, @{n='trusted';e={$_.IsTrusted}} | ConvertTo-Json
+ @{n='provider_name';e={$_.ProviderName}}, @{n='trusted';e={$_.IsTrusted}}
}
}
EOH
diff --git a/lib/chef/resource/windows_ad_join.rb b/lib/chef/resource/windows_ad_join.rb
index 6201b57379..731ce9333e 100644
--- a/lib/chef/resource/windows_ad_join.rb
+++ b/lib/chef/resource/windows_ad_join.rb
@@ -109,12 +109,12 @@ class Chef
cmd << " -Force"
converge_by("join Active Directory domain #{new_resource.domain_name}") do
- ps_run = powershell_out(cmd)
+ ps_run = powershell_exec(cmd)
if ps_run.error?
if sensitive?
raise "Failed to join the domain #{new_resource.domain_name}: *suppressed sensitive resource output*"
else
- raise "Failed to join the domain #{new_resource.domain_name}: #{ps_run.stderr}"
+ raise "Failed to join the domain #{new_resource.domain_name}: #{ps_run.errors}"
end
end
@@ -143,12 +143,12 @@ class Chef
cmd << " -Force"
converge_by("leave Active Directory domain #{node_domain}") do
- ps_run = powershell_out(cmd)
+ ps_run = powershell_exec(cmd)
if ps_run.error?
if sensitive?
raise "Failed to leave the domain #{node_domain}: *suppressed sensitive resource output*"
else
- raise "Failed to leave the domain #{node_domain}: #{ps_run.stderr}"
+ raise "Failed to leave the domain #{node_domain}: #{ps_run.errors}"
end
end
@@ -170,10 +170,10 @@ class Chef
# workgroup the node is a member of.
#
def node_domain
- node_domain = powershell_out!("(Get-WmiObject Win32_ComputerSystem).Domain")
- raise "Failed to check if the system is joined to the domain #{new_resource.domain_name}: #{node_domain.stderr}}" if node_domain.error?
+ node_domain = powershell_exec!("(Get-WmiObject Win32_ComputerSystem).Domain")
+ raise "Failed to check if the system is joined to the domain #{new_resource.domain_name}: #{node_domain.errors}}" if node_domain.error?
- node_domain.stdout.downcase.strip
+ node_domain.result.downcase.strip
end
#
@@ -182,10 +182,10 @@ class Chef
# workgroup.
#
def node_workgroup
- node_workgroup = powershell_out!("(Get-WmiObject Win32_ComputerSystem).Workgroup")
+ node_workgroup = powershell_exec!("(Get-WmiObject Win32_ComputerSystem).Workgroup")
raise "Failed to check if the system is currently a member of a workgroup" if node_workgroup.error?
- node_workgroup.stdout.downcase.strip
+ node_workgroup.result
end
#
diff --git a/lib/chef/resource/windows_certificate.rb b/lib/chef/resource/windows_certificate.rb
index 68874af4d0..2c8c7c72ff 100644
--- a/lib/chef/resource/windows_certificate.rb
+++ b/lib/chef/resource/windows_certificate.rb
@@ -207,16 +207,16 @@ class Chef
when ".der"
out_file.puts(cert_obj.to_der)
when ".cer"
- cert_out = powershell_out("openssl x509 -text -inform DER -in #{cert_obj.to_pem} -outform CER").stdout
+ cert_out = shell_out("openssl x509 -text -inform DER -in #{cert_obj.to_pem} -outform CER").stdout
out_file.puts(cert_out)
when ".crt"
- cert_out = powershell_out("openssl x509 -text -inform DER -in #{cert_obj.to_pem} -outform CRT").stdout
+ cert_out = shell_out("openssl x509 -text -inform DER -in #{cert_obj.to_pem} -outform CRT").stdout
out_file.puts(cert_out)
when ".pfx"
- cert_out = powershell_out("openssl pkcs12 -export -nokeys -in #{cert_obj.to_pem} -outform PFX").stdout
+ cert_out = shell_out("openssl pkcs12 -export -nokeys -in #{cert_obj.to_pem} -outform PFX").stdout
out_file.puts(cert_out)
when ".p7b"
- cert_out = powershell_out("openssl pkcs7 -export -nokeys -in #{cert_obj.to_pem} -outform P7B").stdout
+ cert_out = shell_out("openssl pkcs7 -export -nokeys -in #{cert_obj.to_pem} -outform P7B").stdout
out_file.puts(cert_out)
else
Chef::Log.info("Supported certificate format .pem, .der, .cer, .crt, .pfx and .p7b")
@@ -327,7 +327,7 @@ class Chef
# @return [Boolean] Whether the certificate file is binary encoded or not
#
def binary_cert?
- powershell_out!("file -b --mime-encoding #{new_resource.source}").stdout.strip == "binary"
+ shell_out!("file -b --mime-encoding #{new_resource.source}").stdout.strip == "binary"
end
# Imports the certificate object into cert store
diff --git a/lib/chef/resource/windows_dfs_server.rb b/lib/chef/resource/windows_dfs_server.rb
index 84b2a18c91..fc161f8189 100644
--- a/lib/chef/resource/windows_dfs_server.rb
+++ b/lib/chef/resource/windows_dfs_server.rb
@@ -49,14 +49,14 @@ class Chef
default: 3600
load_current_value do
- ps_results = powershell_out("Get-DfsnServerConfiguration -ComputerName '#{ENV["COMPUTERNAME"]}' | Select LdapTimeoutSec, PreferLogonDC, EnableSiteCostedReferrals, SyncIntervalSec, UseFqdn | ConvertTo-Json")
+ ps_results = powershell_exec("Get-DfsnServerConfiguration -ComputerName '#{ENV["COMPUTERNAME"]}' | Select LdapTimeoutSec, PreferLogonDC, EnableSiteCostedReferrals, SyncIntervalSec, UseFqdn")
if ps_results.error?
raise "The dfs_server resource failed to fetch the current state via the Get-DfsnServerConfiguration PowerShell cmdlet. Is the DFS Windows feature installed?"
end
- Chef::Log.debug("The Get-DfsnServerConfiguration results were #{ps_results.stdout}")
- results = Chef::JSONCompat.from_json(ps_results.stdout)
+ Chef::Log.debug("The Get-DfsnServerConfiguration results were #{ps_results.result}")
+ results = ps_results.result
use_fqdn results["UseFqdn"] || false
ldap_timeout_secs results["LdapTimeoutSec"]
@@ -69,7 +69,10 @@ class Chef
description "Configure DFS settings."
converge_if_changed do
- powershell_out("Set-DfsnServerConfiguration -ComputerName '#{ENV["COMPUTERNAME"]}' EnableSiteCostedReferrals $#{new_resource.enable_site_costed_referrals} -UseFqdn $#{new_resource.use_fqdn} -LdapTimeoutSec #{new_resource.ldap_timeout_secs} -PreferLogonDC $#{new_resource.prefer_login_dc} -SyncIntervalSec #{new_resource.sync_interval_secs}")
+ dfs_cmd = "Set-DfsnServerConfiguration -ComputerName '#{ENV["COMPUTERNAME"]}' -UseFqdn $#{new_resource.use_fqdn} -LdapTimeoutSec #{new_resource.ldap_timeout_secs} -SyncIntervalSec #{new_resource.sync_interval_secs}"
+ dfs_cmd << " -EnableSiteCostedReferrals $#{new_resource.enable_site_costed_referrals}" if new_resource.enable_site_costed_referrals != current_resource.enable_site_costed_referrals
+ dfs_cmd << " -PreferLogonDC $#{new_resource.prefer_login_dc}" if new_resource.prefer_login_dc != current_resource.prefer_login_dc
+ powershell_exec!(dfs_cmd)
end
end
end
diff --git a/lib/chef/resource/windows_firewall_profile.rb b/lib/chef/resource/windows_firewall_profile.rb
index f67d8fb8ed..ada9729699 100644
--- a/lib/chef/resource/windows_firewall_profile.rb
+++ b/lib/chef/resource/windows_firewall_profile.rb
@@ -83,11 +83,11 @@ class Chef
load_current_value do |desired|
ps_get_net_fw_profile = load_firewall_state(desired.profile)
- output = powershell_out(ps_get_net_fw_profile)
- if output.stdout.empty?
+ output = powershell_exec(ps_get_net_fw_profile)
+ if output.result.empty?
current_value_does_not_exist!
else
- state = Chef::JSONCompat.from_json(output.stdout)
+ state = output.result
end
default_inbound_action state["default_inbound_action"]
@@ -130,7 +130,7 @@ class Chef
unless firewall_enabled?(new_resource.profile)
converge_by "Enable the #{new_resource.profile} Firewall Profile" do
cmd = "Set-NetFirewallProfile -Profile #{new_resource.profile} -Enabled \"True\""
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
end
end
@@ -139,7 +139,7 @@ class Chef
if firewall_enabled?(new_resource.profile)
converge_by "Disable the #{new_resource.profile} Firewall Profile" do
cmd = "Set-NetFirewallProfile -Profile #{new_resource.profile} -Enabled \"False\""
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
end
end
@@ -166,12 +166,7 @@ class Chef
return $true
} else {return $false}
CODE
- firewall_status = powershell_out(cmd).stdout
- if /True/.match?(firewall_status)
- true
- elsif /False/.match?(firewall_status)
- false
- end
+ powershell_exec!(cmd).result
end
end
@@ -193,7 +188,7 @@ class Chef
allow_user_ports = $#{profile_name}.AllowUserPorts.ToString()
allow_unicast_response = $#{profile_name}.AllowUnicastResponseToMulticast.ToString()
display_notification = $#{profile_name}.NotifyOnListen.ToString()
- }) | ConvertTo-Json
+ })
EOH
end
end
diff --git a/lib/chef/resource/windows_firewall_rule.rb b/lib/chef/resource/windows_firewall_rule.rb
index 2010c15f89..a6f0614362 100644
--- a/lib/chef/resource/windows_firewall_rule.rb
+++ b/lib/chef/resource/windows_firewall_rule.rb
@@ -19,8 +19,6 @@
# limitations under the License.
#
-require_relative "../json_compat"
-
class Chef
class Resource
class WindowsFirewallRule < Chef::Resource
@@ -159,11 +157,11 @@ class Chef
load_current_value do
load_state_cmd = load_firewall_state(rule_name)
- output = powershell_out(load_state_cmd)
- if output.stdout.empty?
+ output = powershell_exec(load_state_cmd)
+ if output.result.empty?
current_value_does_not_exist!
else
- state = Chef::JSONCompat.from_json(output.stdout)
+ state = output.result
end
# Need to reverse `$rule.Profile.ToString()` in powershell command
@@ -194,17 +192,17 @@ class Chef
:remote_port, :direction, :protocol, :icmp_type, :firewall_action, :profile, :program, :service,
:interface_type, :enabled do
cmd = firewall_command("Set")
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
converge_if_changed :group do
- powershell_out!("Remove-NetFirewallRule -Name '#{new_resource.rule_name}'")
+ powershell_exec!("Remove-NetFirewallRule -Name '#{new_resource.rule_name}'")
cmd = firewall_command("New")
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
else
converge_by("create firewall rule #{new_resource.rule_name}") do
cmd = firewall_command("New")
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
end
end
@@ -214,7 +212,7 @@ class Chef
if current_resource
converge_by("delete firewall rule #{new_resource.rule_name}") do
- powershell_out!("Remove-NetFirewallRule -Name '#{new_resource.rule_name}'")
+ powershell_exec!("Remove-NetFirewallRule -Name '#{new_resource.rule_name}'")
end
else
Chef::Log.info("Firewall rule \"#{new_resource.rule_name}\" doesn't exist. Skipping.")
@@ -320,7 +318,7 @@ class Chef
service = $serviceFilter.Service
interface_type = $interfaceTypeFilter.InterfaceType.ToString()
enabled = [bool]::Parse($rule.Enabled.ToString())
- }) | ConvertTo-Json
+ })
EOH
end
end
diff --git a/lib/chef/resource/windows_security_policy.rb b/lib/chef/resource/windows_security_policy.rb
index 069f240ce5..1b0a285197 100644
--- a/lib/chef/resource/windows_security_policy.rb
+++ b/lib/chef/resource/windows_security_policy.rb
@@ -106,11 +106,11 @@ class Chef
MinimumPasswordAge = $security_options_hash.MinimumPasswordAge
NewGuestName = $security_options_hash.NewGuestName
LockoutBadCount = $security_options_hash.LockoutBadCount
- }) | ConvertTo-Json
+ })
CODE
- output = powershell_out(powershell_code)
- current_value_does_not_exist! if output.stdout.empty?
- state = Chef::JSONCompat.from_json(output.stdout)
+ output = powershell_exec(powershell_code)
+ current_value_does_not_exist! if output.result.empty?
+ state = output.result
if desired.secoption == "ResetLockoutCount" || desired.secoption == "LockoutDuration"
if state["LockoutBadCount"] == "0"
@@ -144,7 +144,7 @@ class Chef
Remove-Item $env:TEMP\\#{security_option}_Export.inf -force
EOH
- powershell_out!(cmd)
+ powershell_exec!(cmd)
end
end
end
diff --git a/lib/chef/resource/windows_share.rb b/lib/chef/resource/windows_share.rb
index 47bf6cfb19..fe1e976747 100644
--- a/lib/chef/resource/windows_share.rb
+++ b/lib/chef/resource/windows_share.rb
@@ -20,7 +20,6 @@
#
require_relative "../resource"
-require_relative "../json_compat"
require_relative "../util/path_helper"
class Chef
@@ -123,19 +122,19 @@ class Chef
# this command selects individual objects because EncryptData & CachingMode have underlying
# types that get converted to their Integer values by ConvertTo-Json & we need to make sure
# those get written out as strings
- share_state_cmd = "Get-SmbShare -Name '#{desired.share_name}' | Select-Object Name,Path, Description, Temporary, CATimeout, ContinuouslyAvailable, ConcurrentUserLimit, EncryptData | ConvertTo-Json -Compress"
+ share_state_cmd = "Get-SmbShare -Name '#{desired.share_name}' | Select-Object Name,Path, Description, Temporary, CATimeout, ContinuouslyAvailable, ConcurrentUserLimit, EncryptData"
Chef::Log.debug("Running '#{share_state_cmd}' to determine share state'")
- ps_results = powershell_out(share_state_cmd)
+ ps_results = powershell_exec(share_state_cmd)
# detect a failure without raising and then set current_resource to nil
if ps_results.error?
- Chef::Log.debug("Error fetching share state: #{ps_results.stderr}")
+ Chef::Log.debug("Error fetching share state: #{ps_results.errors}")
current_value_does_not_exist!
end
- Chef::Log.debug("The Get-SmbShare results were #{ps_results.stdout}")
- results = Chef::JSONCompat.from_json(ps_results.stdout)
+ Chef::Log.debug("The Get-SmbShare results were #{ps_results.result}")
+ results = ps_results.result
path results["Path"]
description results["Description"]
@@ -147,18 +146,18 @@ class Chef
encrypt_data results["EncryptData"]
# folder_enumeration_mode results['FolderEnumerationMode']
- perm_state_cmd = %{Get-SmbShareAccess -Name "#{desired.share_name}" | Select-Object AccountName,AccessControlType,AccessRight | ConvertTo-Json -Compress}
+ perm_state_cmd = %{Get-SmbShareAccess -Name "#{desired.share_name}" | Select-Object AccountName,AccessControlType,AccessRight}
Chef::Log.debug("Running '#{perm_state_cmd}' to determine share permissions state'")
- ps_perm_results = powershell_out(perm_state_cmd)
+ ps_perm_results = powershell_exec(perm_state_cmd)
# we raise here instead of warning like above because we'd only get here if the above Get-SmbShare
# command was successful and that continuing would leave us with 1/2 known state
raise "Could not determine #{desired.share_name} share permissions by running '#{perm_state_cmd}'" if ps_perm_results.error?
- Chef::Log.debug("The Get-SmbShareAccess results were #{ps_perm_results.stdout}")
+ Chef::Log.debug("The Get-SmbShareAccess results were #{ps_perm_results.result}")
- f_users, c_users, r_users = parse_permissions(ps_perm_results.stdout)
+ f_users, c_users, r_users = parse_permissions(ps_perm_results.result)
full_users f_users
change_users c_users
@@ -167,8 +166,7 @@ class Chef
# given the string output of Get-SmbShareAccess parse out
# arrays of full access users, change users, and read only users
- def parse_permissions(results_string)
- json_results = Chef::JSONCompat.from_json(results_string)
+ def parse_permissions(json_results)
json_results = [json_results] unless json_results.is_a?(Array) # single result is not an array
f_users = []
@@ -246,14 +244,16 @@ class Chef
delete_command = "Remove-SmbShare -Name '#{new_resource.share_name}' -Force"
Chef::Log.debug("Running '#{delete_command}' to remove the share")
- powershell_out!(delete_command)
+ powershell_exec!(delete_command)
end
def update_share
- update_command = "Set-SmbShare -Name '#{new_resource.share_name}' -Description '#{new_resource.description}' -Force"
+ update_command = "Set-SmbShare -Name '#{new_resource.share_name}' -Description '#{new_resource.description}' -ConcurrentUserLimit #{new_resource.concurrent_user_limit} -CATimeout #{new_resource.ca_timeout} -EncryptData:#{bool_string(new_resource.encrypt_data)} -ContinuouslyAvailable:#{bool_string(new_resource.continuously_available)} -Force"
+ update_command << " -ScopeName #{new_resource.scope_name}" unless new_resource.scope_name == "*" # passing * causes the command to fail
+ update_command << " -Temporary:#{bool_string(new_resource.temporary)}" if new_resource.temporary # only set true
Chef::Log.debug("Running '#{update_command}' to update the share")
- powershell_out!(update_command)
+ powershell_exec!(update_command)
end
def create_share
@@ -264,7 +264,7 @@ class Chef
share_cmd << " -Temporary:#{bool_string(new_resource.temporary)}" if new_resource.temporary # only set true
Chef::Log.debug("Running '#{share_cmd}' to create the share")
- powershell_out!(share_cmd)
+ powershell_exec!(share_cmd)
# New-SmbShare adds the "Everyone" user with read access no matter what so we need to remove it
# before we add our permissions
@@ -299,7 +299,7 @@ class Chef
grant_command = "Grant-SmbShareAccess -Name '#{new_resource.share_name}' -AccountName \"#{new_resource.send("#{perm_type}_users").join('","')}\" -Force -AccessRight #{perm_type}"
Chef::Log.debug("Running '#{grant_command}' to update the share permissions")
- powershell_out!(grant_command)
+ powershell_exec!(grant_command)
end
end
@@ -330,7 +330,7 @@ class Chef
def revoke_user_permissions(users)
revoke_command = "Revoke-SmbShareAccess -Name '#{new_resource.share_name}' -AccountName \"#{users.join('","')}\" -Force"
Chef::Log.debug("Running '#{revoke_command}' to revoke share permissions")
- powershell_out!(revoke_command)
+ powershell_exec!(revoke_command)
end
# convert True/False into "$True" & "$False"
diff --git a/lib/chef/resource/windows_workgroup.rb b/lib/chef/resource/windows_workgroup.rb
index e506b51257..3c49f7cb3e 100644
--- a/lib/chef/resource/windows_workgroup.rb
+++ b/lib/chef/resource/windows_workgroup.rb
@@ -92,8 +92,8 @@ class Chef
unless workgroup_member?
converge_by("join workstation workgroup #{new_resource.workgroup_name}") do
- ps_run = powershell_out(join_command)
- raise "Failed to join the workgroup #{new_resource.workgroup_name}: #{ps_run.stderr}}" if ps_run.error?
+ ps_run = powershell_exec(join_command)
+ raise "Failed to join the workgroup #{new_resource.workgroup_name}: #{ps_run.errors}}" if ps_run.error?
unless new_resource.reboot == :never
reboot "Reboot to join workgroup #{new_resource.workgroup_name}" do
@@ -119,10 +119,10 @@ class Chef
# @return [Boolean] is the node a member of the workgroup specified in the resource
def workgroup_member?
- node_workgroup = powershell_out!("(Get-WmiObject -Class Win32_ComputerSystem).Workgroup")
+ node_workgroup = powershell_exec!("(Get-WmiObject -Class Win32_ComputerSystem).Workgroup")
raise "Failed to determine if system already a member of workgroup #{new_resource.workgroup_name}" if node_workgroup.error?
- node_workgroup.stdout.downcase.strip == new_resource.workgroup_name.downcase
+ String(node_workgroup.result).downcase.strip == new_resource.workgroup_name.downcase
end
end
end
diff --git a/spec/functional/resource/chocolatey_package_spec.rb b/spec/functional/resource/chocolatey_package_spec.rb
index 24975d2e01..e55c1a453c 100644
--- a/spec/functional/resource/chocolatey_package_spec.rb
+++ b/spec/functional/resource/chocolatey_package_spec.rb
@@ -16,13 +16,13 @@
# limitations under the License.
#
require "spec_helper"
-require "chef/mixin/powershell_out"
+require "chef/mixin/shell_out"
describe Chef::Resource::ChocolateyPackage, :windows_only, :choco_installed do
- include Chef::Mixin::PowershellOut
+ include Chef::Mixin::ShellOut
let(:package_name) { "test-A" }
- let(:package_list) { proc { powershell_out!("choco list -lo -r #{Array(package_name).join(" ")}").stdout.chomp } }
+ let(:package_list) { proc { shell_out!("choco list -lo -r #{Array(package_name).join(" ")}").stdout.chomp } }
let(:package_source) { File.join(CHEF_SPEC_ASSETS, "chocolatey_feed") }
let(:run_context) do
diff --git a/spec/functional/resource/dsc_script_spec.rb b/spec/functional/resource/dsc_script_spec.rb
index 83544cee04..9d18e2f85d 100644
--- a/spec/functional/resource/dsc_script_spec.rb
+++ b/spec/functional/resource/dsc_script_spec.rb
@@ -17,13 +17,13 @@
#
require "spec_helper"
-require "chef/mixin/powershell_out"
+require "chef/mixin/powershell_exec"
require "chef/mixin/windows_architecture_helper"
require "support/shared/integration/integration_helper"
describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
include Chef::Mixin::WindowsArchitectureHelper
- include Chef::Mixin::PowershellOut
+ include Chef::Mixin::PowershellExec
before(:all) do
@temp_dir = ::Dir.mktmpdir("dsc-functional-test")
# enable the HTTP listener if it is not already enabled needed by underlying DSC engine
@@ -33,7 +33,7 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
winrm create winrm/config/Listener?Address=*+Transport=HTTP
}
CODE
- powershell_out!(winrm_code)
+ powershell_exec!(winrm_code)
end
after(:all) do
diff --git a/spec/functional/resource/powershell_package_source_spec.rb b/spec/functional/resource/powershell_package_source_spec.rb
new file mode 100644
index 0000000000..fa95415788
--- /dev/null
+++ b/spec/functional/resource/powershell_package_source_spec.rb
@@ -0,0 +1,103 @@
+#
+# Author:: Matt Wrock (<matt@mattwrock.com>)
+# Copyright:: Copyright (c) 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 "spec_helper"
+require "chef/mixin/powershell_exec"
+
+describe Chef::Resource::PowershellPackageSource, :windows_only do
+ include Chef::Mixin::PowershellExec
+
+ let(:source_name) { "fake" }
+ let(:url) { "https://www.nuget.org/api/v2" }
+ let(:trusted) { true }
+
+ let(:run_context) do
+ Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
+ end
+
+ subject do
+ new_resource = Chef::Resource::PowershellPackageSource.new("test powershell package source", run_context)
+ new_resource.source_name source_name
+ new_resource.url url
+ new_resource.trusted trusted
+ new_resource.provider_name provider_name
+ new_resource
+ end
+
+ let(:provider) do
+ provider = subject.provider_for_action(subject.action)
+ provider
+ end
+
+ shared_examples "package_source" do
+ context "register a package source" do
+ after { remove_package_source }
+
+ it "registers the package source" do
+ subject.run_action(:register)
+ expect(get_installed_package_source_name).to eq(source_name)
+ end
+
+ it "does not register the package source if already installed" do
+ subject.run_action(:register)
+ subject.run_action(:register)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it "updates an existing package source if changed" do
+ subject.run_action(:register)
+ subject.trusted !trusted
+ subject.run_action(:register)
+ expect(subject).to be_updated_by_last_action
+ end
+ end
+
+ context "unregister a package source" do
+ it "unregisters the package source" do
+ subject.run_action(:register)
+ subject.run_action(:unregister)
+ expect(get_installed_package_source_name).to be_empty
+ end
+
+ it "does not unregister the package source if not already installed" do
+ subject.run_action(:unregister)
+ expect(subject).not_to be_updated_by_last_action
+ end
+ end
+ end
+
+ context "with NuGet provider" do
+ let(:provider_name) { "NuGet" }
+
+ it_behaves_like "package_source"
+ end
+
+ context "with PowerShellGet provider" do
+ let(:provider_name) { "PowerShellGet" }
+
+ it_behaves_like "package_source"
+ end
+
+ def get_installed_package_source_name
+ powershell_exec!("(Get-PackageSource -Name #{source_name} -ErrorAction SilentlyContinue).Name").result
+ end
+
+ def remove_package_source
+ pkg_to_remove = Chef::Resource::PowershellPackageSource.new(source_name, run_context)
+ pkg_to_remove.run_action(:unregister)
+ end
+end \ No newline at end of file
diff --git a/spec/functional/resource/windows_certificate_spec.rb b/spec/functional/resource/windows_certificate_spec.rb
index 9c996fe1f8..20d444dd59 100644
--- a/spec/functional/resource/windows_certificate_spec.rb
+++ b/spec/functional/resource/windows_certificate_spec.rb
@@ -16,18 +16,18 @@
#
require "spec_helper"
-require "chef/mixin/powershell_out"
+require "chef/mixin/powershell_exec"
require "chef/resource/windows_certificate"
module WindowsCertificateHelper
- include Chef::Mixin::PowershellOut
+ include Chef::Mixin::PowershellExec
def create_store(store)
path = "Cert:\\LocalMachine\\" + store
command = <<~EOC
New-Item -Path #{path}
EOC
- powershell_out(command)
+ powershell_exec(command)
end
def cleanup(store)
@@ -35,15 +35,19 @@ module WindowsCertificateHelper
command = <<~EOC
Remove-Item -Path #{path} -Recurse
EOC
- powershell_out(command)
+ powershell_exec(command)
end
def no_of_certificates
path = "Cert:\\LocalMachine\\" + store
+ # Seems weird that we have to call dir twice right?
+ # The powershell pki module cache the last dir in module session state
+ # Issuing dir with a different arg (-Force) seems to refresh that state.
command = <<~EOC
- Write-Host (dir #{path} | measure).Count;
+ dir #{path} -Force | Out-Null
+ (dir #{path} | measure).Count
EOC
- powershell_out(command).stdout.to_i
+ powershell_exec(command).result.to_i
end
end
diff --git a/spec/functional/resource/windows_firewall_rule_spec.rb b/spec/functional/resource/windows_firewall_rule_spec.rb
new file mode 100644
index 0000000000..86220c1b71
--- /dev/null
+++ b/spec/functional/resource/windows_firewall_rule_spec.rb
@@ -0,0 +1,93 @@
+#
+# Author:: Matt Wrock (<matt@mattwrock.com>)
+# Copyright:: Copyright (c) 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 "spec_helper"
+require "chef/mixin/powershell_exec"
+
+describe Chef::Resource::WindowsFirewallRule, :windows_only do
+ include Chef::Mixin::PowershellExec
+
+ let(:rule_name) { "fake_rule" }
+ let(:remote_port) { "5555" }
+ let(:enabled) { false }
+
+ let(:run_context) do
+ Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
+ end
+
+ subject do
+ new_resource = Chef::Resource::WindowsFirewallRule.new("test firewall rule", run_context)
+ new_resource.rule_name rule_name
+ new_resource.remote_port remote_port
+ new_resource.enabled enabled
+ new_resource
+ end
+
+ let(:provider) do
+ provider = subject.provider_for_action(subject.action)
+ provider
+ end
+
+ context "create a new rule" do
+ after { delete_rule }
+
+ it "creates the rule" do
+ subject.run_action(:create)
+ expect(get_installed_rule_name).to eq(rule_name)
+ expect(get_installed_rule_remote_port).to eq(remote_port)
+ end
+
+ it "does not create rule if it already exists" do
+ subject.run_action(:create)
+ subject.run_action(:create)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it "updates the rule if it changed" do
+ subject.run_action(:create)
+ subject.remote_port = "7777"
+ subject.run_action(:create)
+ expect(get_installed_rule_remote_port).to eq("7777")
+ end
+ end
+
+ context "delete a rule" do
+ it "deletes an existing rule" do
+ subject.run_action(:create)
+ subject.run_action(:delete)
+ expect(get_installed_rule_name).to be_empty
+ end
+
+ it "does not delete rule if it does not exist" do
+ subject.run_action(:delete)
+ expect(subject).not_to be_updated_by_last_action
+ end
+ end
+
+ def get_installed_rule_name
+ powershell_exec!("(Get-NetFirewallRule -Name #{rule_name} -ErrorAction SilentlyContinue).Name").result
+ end
+
+ def get_installed_rule_remote_port
+ powershell_exec!("((Get-NetFirewallRule -Name #{rule_name} -ErrorAction SilentlyContinue) | Get-NetFirewallPortFilter).RemotePort").result
+ end
+
+ def delete_rule
+ rule_to_remove = Chef::Resource::WindowsFirewallRule.new(rule_name, run_context)
+ rule_to_remove.run_action(:delete)
+ end
+end
diff --git a/spec/functional/resource/windows_share_spec.rb b/spec/functional/resource/windows_share_spec.rb
new file mode 100644
index 0000000000..6fae7d45d3
--- /dev/null
+++ b/spec/functional/resource/windows_share_spec.rb
@@ -0,0 +1,103 @@
+#
+# Author:: Matt Wrock (<matt@mattwrock.com>)
+# Copyright:: Copyright (c) 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 "spec_helper"
+require "chef/mixin/powershell_exec"
+
+describe Chef::Resource::WindowsShare, :windows_only do
+ include Chef::Mixin::PowershellExec
+
+ let(:share_name) { "fake_share" }
+ let(:path) { ENV["temp"] }
+ let(:concurrent_user_limit) { 7 }
+ let(:full_users) { ["#{ENV["USERNAME"]}"] }
+
+ let(:run_context) do
+ node = Chef::Node.new
+ node.default["hostname"] = ENV["COMPUTERNAME"]
+ Chef::RunContext.new(node, {}, Chef::EventDispatch::Dispatcher.new)
+ end
+
+ subject do
+ new_resource = Chef::Resource::WindowsShare.new("test windows share", run_context)
+ new_resource.share_name share_name
+ new_resource.path path
+ new_resource.concurrent_user_limit concurrent_user_limit
+ new_resource.full_users full_users
+ new_resource
+ end
+
+ let(:provider) do
+ provider = subject.provider_for_action(subject.action)
+ provider
+ end
+
+ context "create a new share" do
+ after { delete_share }
+
+ it "creates the share" do
+ subject.run_action(:create)
+ share = get_installed_share
+ expect(share["Name"]).to eq(share_name)
+ expect(share["Path"]).to eq(path)
+ expect(get_installed_share_access["AccountName"]).to eq("#{ENV["COMPUTERNAME"]}\\#{full_users[0]}")
+ end
+
+ it "does not create share if it already exists" do
+ subject.run_action(:create)
+ subject.run_action(:create)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it "updates the share if it changed" do
+ subject.run_action(:create)
+ subject.concurrent_user_limit 8
+ subject.full_users ["BUILTIN\\Administrators"]
+ subject.run_action(:create)
+ share = get_installed_share
+ expect(share["ConcurrentUserLimit"]).to eq(8)
+ expect(get_installed_share_access["AccountName"]).to eq("BUILTIN\\Administrators")
+ end
+
+ end
+
+ context "delete a share" do
+ it "deletes an existing share" do
+ subject.run_action(:create)
+ subject.run_action(:delete)
+ expect(get_installed_share).to be_empty
+ end
+
+ it "does not delete share if it does not exist" do
+ subject.run_action(:delete)
+ expect(subject).not_to be_updated_by_last_action
+ end
+ end
+
+ def get_installed_share
+ powershell_exec!("Get-SmbShare -Name #{share_name} -ErrorAction SilentlyContinue").result
+ end
+
+ def get_installed_share_access
+ powershell_exec!("Get-SmbShareAccess -Name #{share_name} -ErrorAction SilentlyContinue").result
+ end
+
+ def delete_share
+ rule_to_remove = Chef::Resource::WindowsShare.new(share_name, run_context)
+ rule_to_remove.run_action(:delete)
+ end
+end
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 60990f73a5..b29c860f30 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -2,11 +2,9 @@ require "fcntl"
require "chef/mixin/shell_out"
require "ohai/mixin/http_helper"
require "ohai/mixin/gce_metadata"
-require "chef/mixin/powershell_out"
class ShellHelpers
extend Chef::Mixin::ShellOut
- extend Chef::Mixin::PowershellOut
end
# magic stolen from bundler/spec/support/less_than_proc.rb
@@ -242,11 +240,15 @@ def ifconfig?
end
def choco_installed?
- result = ShellHelpers.powershell_out("choco --version")
+ result = ShellHelpers.shell_out("choco --version")
result.stderr.empty?
+rescue
+ false
end
def pwsh_installed?
- result = ShellHelpers.powershell_out("pwsh.exe --version")
+ result = ShellHelpers.shell_out("pwsh.exe --version")
result.stderr.empty?
+rescue
+ false
end
diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb
index 96b17d90f2..ba5739fe55 100644
--- a/spec/unit/provider/package/chocolatey_spec.rb
+++ b/spec/unit/provider/package/chocolatey_spec.rb
@@ -501,8 +501,7 @@ describe "behavior when Chocolatey is not installed" do
before do
# the shellout sometimes returns "", but test nil to be safe.
- allow(provider).to receive(:choco_install_path).and_return(nil)
- provider.instance_variable_set("@choco_install_path", nil)
+ allow(provider).to receive(:choco_install_path).and_return("")
# we don't care what this returns, but we have to let it be called.
allow(provider).to receive(:shell_out_compacted!).and_return(double(stdout: ""))
diff --git a/spec/unit/resource/powershell_package_source_spec.rb b/spec/unit/resource/powershell_package_source_spec.rb
index 2640d9f3c5..1032902a0f 100644
--- a/spec/unit/resource/powershell_package_source_spec.rb
+++ b/spec/unit/resource/powershell_package_source_spec.rb
@@ -87,58 +87,58 @@ describe Chef::Resource::PowershellPackageSource do
context "#register" do
it "builds a minimal command" do
- expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted'")
+ expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' | Out-Null")
end
it "builds a command with trusted set to true" do
resource.trusted(true)
- expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Trusted'")
+ expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Trusted' | Out-Null")
end
it "builds a command with a publish location" do
resource.publish_location("https://mygallery.company.co/api/v2/package")
- expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -PublishLocation 'https://mygallery.company.co/api/v2/package'")
+ expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -PublishLocation 'https://mygallery.company.co/api/v2/package' | Out-Null")
end
it "builds a command with a script source location" do
resource.script_source_location("https://mygallery.company.co/api/v2/scripts")
- expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptSourceLocation 'https://mygallery.company.co/api/v2/scripts'")
+ expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptSourceLocation 'https://mygallery.company.co/api/v2/scripts' | Out-Null")
end
it "builds a command with a script publish location" do
resource.script_publish_location("https://mygallery.company.co/api/v2/scripts/package")
- expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptPublishLocation 'https://mygallery.company.co/api/v2/scripts/package'")
+ expect(provider.build_ps_repository_command("Register", resource)).to eql("Register-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptPublishLocation 'https://mygallery.company.co/api/v2/scripts/package' | Out-Null")
end
end
context "#set" do
it "builds a minimal command" do
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' | Out-Null")
end
it "builds a command to change the url" do
resource.url("https://othergallery.company.co/api/v2/")
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://othergallery.company.co/api/v2/' -InstallationPolicy 'Untrusted'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://othergallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' | Out-Null")
end
it "builds a command with trusted set to true" do
resource.trusted(true)
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Trusted'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Trusted' | Out-Null")
end
it "builds a command with a publish location" do
resource.publish_location("https://mygallery.company.co/api/v2/package")
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -PublishLocation 'https://mygallery.company.co/api/v2/package'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -PublishLocation 'https://mygallery.company.co/api/v2/package' | Out-Null")
end
it "builds a command with a script source location" do
resource.script_source_location("https://mygallery.company.co/api/v2/scripts")
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptSourceLocation 'https://mygallery.company.co/api/v2/scripts'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptSourceLocation 'https://mygallery.company.co/api/v2/scripts' | Out-Null")
end
it "builds a command with a script publish location" do
resource.script_publish_location("https://mygallery.company.co/api/v2/scripts/package")
- expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptPublishLocation 'https://mygallery.company.co/api/v2/scripts/package'")
+ expect(provider.build_ps_repository_command("Set", resource)).to eql("Set-PSRepository -Name 'MyGallery' -SourceLocation 'https://mygallery.company.co/api/v2/' -InstallationPolicy 'Untrusted' -ScriptPublishLocation 'https://mygallery.company.co/api/v2/scripts/package' | Out-Null")
end
end
end
@@ -151,42 +151,42 @@ describe Chef::Resource::PowershellPackageSource do
context "#register" do
it "builds a minimal command" do
- expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$false -ProviderName 'NuGet'")
+ expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$false -ProviderName 'NuGet' | Out-Null")
end
it "builds a command with trusted set to true" do
resource.trusted(true)
- expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$true -ProviderName 'NuGet'")
+ expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$true -ProviderName 'NuGet' | Out-Null")
end
it "builds a command with a different provider" do
resource.source_name("choco")
resource.url("https://chocolatey.org/api/v2/")
resource.provider_name("chocolatey")
- expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'choco' -Location 'https://chocolatey.org/api/v2/' -Trusted:$false -ProviderName 'chocolatey'")
+ expect(provider.build_package_source_command("Register", resource)).to eql("Register-PackageSource -Name 'choco' -Location 'https://chocolatey.org/api/v2/' -Trusted:$false -ProviderName 'chocolatey' | Out-Null")
end
end
context "#set" do
it "builds a minimal command" do
- expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$false -ProviderName 'NuGet'")
+ expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$false -ProviderName 'NuGet' | Out-Null")
end
it "builds a command to change the url" do
resource.url("https://nuget.company.co/api/v2/")
- expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'https://nuget.company.co/api/v2/' -Trusted:$false -ProviderName 'NuGet'")
+ expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'https://nuget.company.co/api/v2/' -Trusted:$false -ProviderName 'NuGet' | Out-Null")
end
it "builds a command with trusted set to true" do
resource.trusted(true)
- expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$true -ProviderName 'NuGet'")
+ expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'NuGet' -Location 'http://nuget.org/api/v2/' -Trusted:$true -ProviderName 'NuGet' | Out-Null")
end
it "builds a command with a different provider" do
resource.source_name("choco")
resource.url("https://chocolatey.org/api/v2/")
resource.provider_name("chocolatey")
- expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'choco' -Location 'https://chocolatey.org/api/v2/' -Trusted:$false -ProviderName 'chocolatey'")
+ expect(provider.build_package_source_command("Set", resource)).to eql("Set-PackageSource -Name 'choco' -Location 'https://chocolatey.org/api/v2/' -Trusted:$false -ProviderName 'chocolatey' | Out-Null")
end
end
end
@@ -205,13 +205,13 @@ describe Chef::Resource::PowershellPackageSource do
describe "#package_source_exists?" do
it "returns true if it exists" do
- allow(provider).to receive(:powershell_out!).with("(Get-PackageSource -Name 'MyGallery' -WarningAction SilentlyContinue).Name").and_return(double("powershell_out!", stdout: "MyGallery\r\n"))
+ allow(provider).to receive(:powershell_exec!).with("(Get-PackageSource -Name 'MyGallery' -ErrorAction SilentlyContinue).Name").and_return(double("powershell_exec!", result: "MyGallery\r\n"))
resource.source_name("MyGallery")
expect(provider.package_source_exists?).to eql(true)
end
it "returns false if it doesn't exist" do
- allow(provider).to receive(:powershell_out!).with("(Get-PackageSource -Name 'MyGallery' -WarningAction SilentlyContinue).Name").and_return(double("powershell_out!", stdout: ""))
+ allow(provider).to receive(:powershell_exec!).with("(Get-PackageSource -Name 'MyGallery' -ErrorAction SilentlyContinue).Name").and_return(double("powershell_exec!", result: ""))
resource.source_name("MyGallery")
expect(provider.package_source_exists?).to eql(false)
end