summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2018-02-20 16:17:49 -0800
committerGitHub <noreply@github.com>2018-02-20 16:17:49 -0800
commit77f787f96c1e6bc4cc99c2c26dc3d7b4b68a9dca (patch)
tree6e913aa575b023831dbfc6e9a21e5b43149360e6
parent1b84b4ddf607dfad71edcd4ee602bbb8f36696ec (diff)
parent1d41fef6963e64806194665f3e49c6c2f0f1398d (diff)
downloadchef-77f787f96c1e6bc4cc99c2c26dc3d7b4b68a9dca.tar.gz
Merge pull request #6878 from chef/macos_userdefaults
Add macos_user_defaults resource from mac_os_x cookbook
-rw-r--r--lib/chef/resource/macos_userdefaults.rb126
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--spec/unit/resource/macos_user_defaults_spec.rb45
3 files changed, 172 insertions, 0 deletions
diff --git a/lib/chef/resource/macos_userdefaults.rb b/lib/chef/resource/macos_userdefaults.rb
new file mode 100644
index 0000000000..c0066c84b5
--- /dev/null
+++ b/lib/chef/resource/macos_userdefaults.rb
@@ -0,0 +1,126 @@
+#
+# Copyright:: 2011-2018, Joshua Timberman
+# Copyright:: 2018, Chef Software, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/resource"
+
+class Chef
+ class Resource
+ class MacosUserDefaults < Chef::Resource
+ # align with apple's marketing department
+ resource_name :macos_userdefaults
+ provides :mac_os_x_userdefaults
+ provides :macos_userdefaults
+
+ introduced "14.0"
+
+ description "Use the macos_userdefaults resource to manage the macOS user defaults"\
+ " system. The properties to the resource are passed to the defaults command"\
+ " and the parameters follow convention of the macOS command. See the defaults(1)"\
+ " man page for details on how the tool works."
+
+ property :domain,
+ String,
+ description: "The domain the defaults belong to.",
+ required: true
+
+ property :global,
+ [true, false],
+ description: "Whether the domain is global.",
+ default: false
+
+ property :key,
+ String,
+ description: "The preference key."
+
+ property :value,
+ [Integer, Float, String, true, false, Hash, Array],
+ description: "The value of the key.",
+ coerce: proc { |v| coerce_booleans(v) },
+ required: true
+
+ property :type,
+ String,
+ description: "Value type of the preference key.",
+ default: ""
+
+ property :user,
+ String,
+ description: "User for which to set the default."
+
+ property :sudo,
+ [true, false],
+ description: "Set to true if the setting requires privileged access to modify.",
+ default: false,
+ desired_state: false
+
+ property :is_set,
+ [true, false],
+ description: "",
+ default: false,
+ desired_state: false
+
+ # coerce various ways of representing a boolean into either 0 (false) or 1 (true)
+ # which is what the defaults CLI expects. Why? Well defaults itself accepts a few
+ # different formats, but when you do a read command it all comes back as 1 or 0.
+ def coerce_booleans(val)
+ return 1 if [true, "TRUE", "1", "true", "YES", "yes"].include?(val)
+ return 0 if [false, "FALSE", "0", "false", "NO", "no"].include?(val)
+ val
+ end
+
+ load_current_value do |desired|
+ drcmd = "defaults read '#{desired.domain}' "
+ drcmd << "'#{desired.key}' " if desired.key
+ shell_out_opts = {}
+ shell_out_opts[:user] = desired.user unless desired.user.nil?
+ vc = shell_out("#{drcmd} | grep -qx '#{desired.value}'", shell_out_opts)
+ is_set vc.exitstatus == 0 ? true : false
+ end
+
+ action :write do
+ description "Write the setting to the specified domain"
+
+ unless current_value.is_set
+ cmd = ["defaults write"]
+ cmd.unshift("sudo") if new_resource.sudo
+
+ cmd << if new_resource.global
+ "NSGlobalDomain"
+ else
+ "'#{new_resource.domain}'"
+ end
+
+ cmd << "'#{new_resource.key}'" if new_resource.key
+ value = new_resource.value
+ type = new_resource.type.empty? ? value_type(value) : new_resource.type
+ # creates a string of Key1 Value1 Key2 Value2...
+ value = value.map { |k, v| "\"#{k}\" \"#{v}\"" }.join(" ") if type == "dict"
+ if type == "array"
+ value = value.join("' '")
+ value = "'#{value}'"
+ end
+ cmd << "-#{type}" if type
+ cmd << value
+
+ declare_resource(:execute, cmd.join(" ")) do
+ user new_resource.user unless new_resource.user.nil?
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 60f3ad51f0..c10bf98b2f 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -49,6 +49,7 @@ require "chef/resource/launchd"
require "chef/resource/link"
require "chef/resource/log"
require "chef/resource/macports_package"
+require "chef/resource/macos_userdefaults"
require "chef/resource/mdadm"
require "chef/resource/mount"
require "chef/resource/ohai"
diff --git a/spec/unit/resource/macos_user_defaults_spec.rb b/spec/unit/resource/macos_user_defaults_spec.rb
new file mode 100644
index 0000000000..6ef82853cc
--- /dev/null
+++ b/spec/unit/resource/macos_user_defaults_spec.rb
@@ -0,0 +1,45 @@
+#
+# 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::MacosUserDefaults do
+
+ let(:resource) { Chef::Resource::MacosUserDefaults.new("foo") }
+
+ it "has a resource name of :macos_userdefaults" do
+ expect(resource.resource_name).to eql(:macos_userdefaults)
+ end
+
+ it "has a default action of install" do
+ expect(resource.action).to eql([:write])
+ end
+
+ [true, "TRUE", "1", "true", "YES", "yes"].each do |val|
+ it "coerces value property from #{val} to 1" do
+ resource.value val
+ expect(resource.value).to eql(1)
+ end
+ end
+
+ [false, "FALSE", "0", "false", "NO", "no"].each do |val|
+ it "coerces value property from #{val} to 0" do
+ resource.value val
+ expect(resource.value).to eql(0)
+ end
+ end
+end