summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2018-09-14 11:27:55 -0700
committerGitHub <noreply@github.com>2018-09-14 11:27:55 -0700
commitbacdb274870acea0eb689669bd5c903ccfeae20d (patch)
tree756c96a1ec18df3436d94f3ace95f7811bd39ae7
parenta9a04fbb0029b7711404be615c6c1e14bb26f6c2 (diff)
parentedb22e06e1a227e108998ad1528c38cecde0b3bd (diff)
downloadchef-bacdb274870acea0eb689669bd5c903ccfeae20d.tar.gz
Merge pull request #7564 from derekgroh/feature/windows_ad_join
windows_workgroup Resource for joining Windows Workgroups
-rw-r--r--RELEASE_NOTES.md4
-rw-r--r--lib/chef/resource/windows_workgroup.rb101
-rw-r--r--lib/chef/resources.rb3
-rw-r--r--spec/unit/resource/windows_workgroup_spec.rb47
4 files changed, 154 insertions, 1 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 705155bdd1..5e37f3aeb5 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -529,6 +529,10 @@ Use the windows_printer_port resource to create and delete TCP/IPv4 printer port
Use the windows_shortcut resource to create shortcut files on Windows. This resource was ported from the `windows` community cookbook.
+### windows_workgroup
+
+Use the windows_workgroup resource to join a Windows Workgroup and reboot the node. This resource is based on the `windows_ad_join` resource.
+
## Custom Resource Improvements
We've expanded the DSL for custom resources with new functionality to better document your resources and help users with errors and upgrades. Many resources in Chef itself are now using this new functionality, and you'll see more updated to take advantage of this it in the future.
diff --git a/lib/chef/resource/windows_workgroup.rb b/lib/chef/resource/windows_workgroup.rb
new file mode 100644
index 0000000000..7d0f462caf
--- /dev/null
+++ b/lib/chef/resource/windows_workgroup.rb
@@ -0,0 +1,101 @@
+#
+# Author:: Derek Groh (<derekgroh@github.io>)
+# Copyright:: 2018, Derek Groh
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/resource"
+require "chef/mixin/powershell_out"
+
+class Chef
+ class Resource
+ class WindowsWorkgroup < Chef::Resource
+ resource_name :windows_workgroup
+ provides :windows_workgroup
+
+ include Chef::Mixin::PowershellOut
+
+ description "Use the windows_workgroup resource to join change the workgroup of a machine."
+ introduced "14.5"
+
+ property :workgroup_name, String,
+ description: "The name of the workgroup for the computer.",
+ validation_message: "The 'workgroup_name' property must not contain spaces.",
+ regex: /^\S*$/, # no spaces
+ name_property: true
+
+ property :user, String,
+ description: "The local administrator user to use to change the workgroup."
+
+ property :password, String,
+ description: "The password for the local administrator user."
+
+ property :reboot, Symbol,
+ equal_to: [:immediate, :delayed, :never, :request_reboot, :reboot_now],
+ validation_message: "The reboot property accepts :immediate (reboot as soon as the resource completes), :delayed (reboot once the Chef run completes), and :never (Don't reboot)",
+ description: "Controls the system reboot behavior post workgroup joining. Reboot immediately, after the Chef run completes, or never. Note that a reboot is necessary for changes to take effect.",
+ default: :immediate
+
+ # define this again so we can default it to true. Otherwise failures print the password
+ property :sensitive, [TrueClass, FalseClass],
+ default: true
+
+ action :join do
+ description "Update the workgroup."
+
+ unless workgroup_member?
+ cmd = ""
+ cmd << "$pswd = ConvertTo-SecureString \'#{new_resource.password}\' -AsPlainText -Force;" if new_resource.password
+ cmd << "$credential = New-Object System.Management.Automation.PSCredential (\"#{new_resource.user}\",$pswd);" if new_resource.password
+ cmd << "Add-Computer -WorkgroupName #{new_resource.workgroup_name}"
+ cmd << " -Credential $credential" if new_resource.password
+ cmd << " -Force"
+
+ converge_by("join workstation workgroup #{new_resource.workgroup_name}") do
+ ps_run = powershell_out(cmd)
+ raise "Failed to join the workgroup #{new_resource.workgroup_name}: #{ps_run.stderr}}" if ps_run.error?
+
+ unless new_resource.reboot == :never
+ reboot "Reboot to join workgroup #{new_resource.workgroup_name}" do
+ action clarify_reboot(new_resource.reboot)
+ reason "Reboot to join workgroup #{new_resource.workgroup_name}"
+ end
+ end
+ end
+ end
+ end
+
+ action_class do
+ # This resource historically took `:immediate` and `:delayed` as arguments to the reboot property but then
+ # tried to shove that straight to the `reboot` resource which objected strenuously
+ def clarify_reboot(reboot_action)
+ case reboot_action
+ when :immediate
+ :reboot_now
+ when :delayed
+ :request_reboot
+ else
+ reboot_action
+ end
+ end
+
+ def workgroup_member?
+ node_workgroup = powershell_out!("(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
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index a96dcdda4a..d99aeed3ad 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -57,6 +57,7 @@ require "chef/resource/kernel_module"
require "chef/resource/ksh"
require "chef/resource/launchd"
require "chef/resource/link"
+require "chef/resource/locale"
require "chef/resource/log"
require "chef/resource/macports_package"
require "chef/resource/macos_userdefaults"
@@ -139,4 +140,4 @@ require "chef/resource/windows_printer"
require "chef/resource/windows_printer_port"
require "chef/resource/windows_shortcut"
require "chef/resource/windows_task"
-require "chef/resource/locale"
+require "chef/resource/windows_workgroup"
diff --git a/spec/unit/resource/windows_workgroup_spec.rb b/spec/unit/resource/windows_workgroup_spec.rb
new file mode 100644
index 0000000000..3d7acec2fb
--- /dev/null
+++ b/spec/unit/resource/windows_workgroup_spec.rb
@@ -0,0 +1,47 @@
+#
+# Copyright:: Copyright 2018, 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"
+
+describe Chef::Resource::WindowsWorkgroup do
+ let(:resource) { Chef::Resource::WindowsWorkgroup.new("example") }
+
+ it "sets resource name as :windows_workgroup" do
+ expect(resource.resource_name).to eql(:windows_workgroup)
+ end
+
+ it "the workgroup_name property is the name_property" do
+ expect(resource.workgroup_name).to eql("example")
+ end
+
+ it "sets the default action as :join" do
+ expect(resource.action).to eql([:join])
+ end
+
+ it "supports :join action" do
+ expect { resource.action :join }.not_to raise_error
+ end
+
+ it "accepts :immediate, :reboot_now, :request_reboot, :delayed, or :never values for 'reboot' property" do
+ expect { resource.reboot :immediate }.not_to raise_error
+ expect { resource.reboot :delayed }.not_to raise_error
+ expect { resource.reboot :reboot_now }.not_to raise_error
+ expect { resource.reboot :request_reboot }.not_to raise_error
+ expect { resource.reboot :never }.not_to raise_error
+ expect { resource.reboot :nopenope }.to raise_error(ArgumentError)
+ end
+end