Skip to content

Commit

Permalink
Merge pull request chef#8379 from jasonwbarnett/feature/add-leave-act…
Browse files Browse the repository at this point in the history
…ion-to-windows_ad_join

windows_ad_join: Add :leave action to for leaving an AD domain
  • Loading branch information
tas50 authored Oct 9, 2019
2 parents 68dfb74 + 9b54fdc commit 11311c4
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
75 changes: 72 additions & 3 deletions lib/chef/resource/windows_ad_join.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,18 @@ class WindowsAdJoin < Chef::Resource
description: "Specifies a new hostname for the computer in the new domain.",
introduced: "14.5"

property :workgroup_name, String,
description: "Specifies the name of a workgroup to which the computer is added to when it is removed from the domain. The default value is WORKGROUP. This property is only applicable to the :leave action.",
introduced: "15.0"

# define this again so we can default it to true. Otherwise failures print the password
property :sensitive, [TrueClass, FalseClass],
default: true, desired_state: false

action :join do
description "Join the Active Directory domain."

unless on_domain?
unless on_desired_domain?
cmd = "$pswd = ConvertTo-SecureString \'#{new_resource.domain_password}\' -AsPlainText -Force;"
cmd << "$credential = New-Object System.Management.Automation.PSCredential (\"#{new_resource.domain_user}@#{new_resource.domain_name}\",$pswd);"
cmd << "Add-Computer -DomainName #{new_resource.domain_name} -Credential $credential"
Expand Down Expand Up @@ -92,12 +96,77 @@ class WindowsAdJoin < Chef::Resource
end
end

action :leave do
description "Leave the Active Directory domain."

if joined_to_domain?
cmd = ""
cmd << "$pswd = ConvertTo-SecureString \'#{new_resource.domain_password}\' -AsPlainText -Force;"
cmd << "$credential = New-Object System.Management.Automation.PSCredential (\"#{new_resource.domain_user}@#{new_resource.domain_name}\",$pswd);"
cmd << "Remove-Computer"
cmd << " -UnjoinDomainCredential $credential"
cmd << " -NewName \"#{new_resource.new_hostname}\"" if new_resource.new_hostname
cmd << " -WorkgroupName \"#{new_resource.workgroup_name}\"" if new_resource.workgroup_name
cmd << " -Force"

converge_by("leave Active Directory domain #{node_domain}") do
ps_run = powershell_out(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}"
end
end

unless new_resource.reboot == :never
reboot "Reboot to leave domain #{new_resource.domain_name}" do
action clarify_reboot(new_resource.reboot)
reason "Reboot to leave domain #{new_resource.domain_name}"
end
end
end
end
end

action_class do
def on_domain?
#
# @return [String] The domain name the node is joined to. When the node
# is not joined to a domain this will return the name of the
# 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.stdout.downcase.strip == new_resource.domain_name.downcase
node_domain.stdout.downcase.strip
end

#
# @return [String] The workgroup the node is a member of. This will
# return an empty string if the system is not a member of a
# workgroup.
#
def node_workgroup
node_workgroup = powershell_out!("(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
end

#
# @return [true, false] Whether or not the node is joined to ANY domain
#
def joined_to_domain?
node_workgroup.empty? && !node_domain.empty?
end

#
# @return [true, false] Whether or not the node is joined to the domain
# defined by the resource :domain_name property.
#
def on_desired_domain?
node_domain == new_resource.domain_name.downcase
end

# This resource historically took `:immediate` and `:delayed` as arguments to the reboot property but then
Expand Down
4 changes: 4 additions & 0 deletions spec/unit/resource/windows_ad_join_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
expect { resource.action :join }.not_to raise_error
end

it "supports :leave action" do
expect { resource.action :leave }.not_to raise_error
end

it "only accepts FQDNs for the domain_name property" do
expect { resource.domain_name "example" }.to raise_error(ArgumentError)
end
Expand Down

0 comments on commit 11311c4

Please sign in to comment.