diff --git a/.gitignore b/.gitignore index 0c6117d..c06a73d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -pkg \ No newline at end of file +pkg +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..88d8f02 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +License: BSD 2-Clause License + +Copyright (c) Robin Laurén / Reaktor (c) 2017, All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. Redistributions in binary form must +reproducethe above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the +distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Modulefile b/Modulefile deleted file mode 100644 index 9f666ce..0000000 --- a/Modulefile +++ /dev/null @@ -1,6 +0,0 @@ -name 'grahamgilbert-macdefaults' -version '0.0.1' -summary 'Manage defaults on an OS X system' -author 'Graham Gilbert' -source 'https://github.com/pebbleit/puppet-macdefaults.git' -license 'Apache 2.0' diff --git a/README.md b/README.md index 164e750..44eb796 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,118 @@ -OS X Defaults module for Puppet -================== - -This module manages defaults on OS X. I didn't write 90% of this, but I can't for the life of me remember where I found it. I'm putting it on here for posterity. - -#Usage - -Possible valuse for ``type`` are: - -* string -* data -* int -* float -* bool -* data -* array -* array-add -* dict -* dict-add - -Example Puppet Code: - - include macdefaults - - mac-defaults { "set-a4": - domain => '/Library/Preferences/com.apple.print.PrintingPrefs', - key => 'DefaultPaperID', - type => 'string', - value => "iso-a4", - } \ No newline at end of file +# macOS Defaults module for Puppet + +## Note of potential disaster + +This module has not been tested. It was rolled straight into production and +let to its own devices. It will probably blow up your whole server park unless +you are careful. If it does, i'd appreciate a patch, so that it won't blow up +any other server park. + +#### Table of Contents + +1. [Description](#description) +1. [Setup - The basics of getting started with macdefaults](#setup) + * [What macdefaults affects](#what-macdefaults-affects) + * [Setup requirements](#setup-requirements) +1. [Usage - Configuration options and additional functionality](#usage) +1. [Reference - An under-the-hood peek at what the module is doing and how](#reference) +1. [Limitations - OS compatibility, etc.](#limitations) +1. [Development - Guide for contributing to the module](#development) + +## Description + +Set or remove your macOS `defaults` with macdefaults. + +This module is a re-write of the two modules i found floating around the +interwebs for just this, namely: + +* https://github.com/wfarr/puppet-osx_defaults by Will Farrington, and +* https://github.com/pebbleit/puppet-macdefaults by Graham Gilbert + +Neither of these have been updated for years, and one of the files contained +some kind of incompatibility with Puppet 4. So here's my mash-up of these two +modules. + +The module includes some rudimentary error checking for missing and ill-formed +values. + +## Setup + +Clone or download this module to live nicely among your other puppet modules. +Cross your fingers. Breathe normally. + +### What macdefaults affects + +You can set or remove any macOS `defaults` with this module, but you need to +know the correct domain. For many fun and useful things to muck around with, +have a look at https://github.com/boxen/puppet-osx. + +### Setup Requirements + +Requires `puppetlabs-stdlib` version 4.0.0 or higher, and a Mac to run the +module on. + +## Usage + +In a manifest dealing with a macOS node (you know, a Mac), include something +along the lines of + +``` +macdefaults { "AppleUpdatesThroughMunki": + ensure => present, + domain => "/Library/Preferences/ManagedInstalls", + key => "InstallAppleSoftwareUpdates", + type => 'bool', + value => True, +} +``` +The example code above would ensure that Macs use Munki for Apple system udates. + +Possible values for `type` are those of OS X Defaults; ie. `string`, `data`, +`int` (or `integer`), `float`, `bool` (or `boolean`), `array`, `array-add`, +`dict` and `dict-add`. That said, i've never tested any other values than `int`; +i just copied this from Graham's macdefaults README.md, so don't take my word +for it. Read the source. Understand what you do. And send me a patch if you find +a bug. + +The code includes some checking for idempotency. It used to be wicked clever, +but rather opaque, so i expanded the code for readability. You can still find +the original and quote ingenious checking code for boolean values in Gilbert's +and Farrington's code. + +I removed the quotes inside some of the code, which might break stuff up. +Please use quotes around any strange string values. + +Yet untested, but according to the puppet [language reference on case matching +](https://docs.puppet.com/puppet/latest/reference/lang_conditional.html#case-matching-1), +the values for the `bool` type _should_ be case-insensitive. + +## Reference + +* `man defaults` on your Mac +* https://github.com/wfarr/puppet-osx_defaults by Will Farrington, and +* https://github.com/pebbleit/puppet-macdefaults by Graham Gilbert +* https://github.com/boxen/puppet-osx by Boxen + +## Limitations + +Me, mostly. + +## Development + +Merge/pull requests welcome. + +## Release Notes/Contributors/Etc. + +Second major rewrite. Works on my machine. Only tested with the `Int` type. Your +mileage will most certainly vary. Handle with care and have mercy. + +If you think there are a lot of comments in the manifest file, it's just because +that's how Puppet does it when you create a new module with `puppet module +generate macdefaults`. + +## Bug warning + +This module was originally called osx_defaults (from Will Farrington's code) but +i chose to go with the name macdefaults, as OS X is now known as macOS rather +than OS X. I hope i managed to find-replace all relevant instances of the old +name in the code! diff --git a/examples/init.pp b/examples/init.pp new file mode 100644 index 0000000..fbd0e73 --- /dev/null +++ b/examples/init.pp @@ -0,0 +1,12 @@ +# The baseline for module testing used by Puppet Labs is that each manifest +# should have a corresponding test manifest that declares that class or defined +# type. +# +# Tests are then run by using puppet apply --noop (to check for compilation +# errors and view a log of events) or by fully applying the test in a virtual +# environment (to compare the resulting system state to the desired state). +# +# Learn more about module testing here: +# https://docs.puppet.com/guides/tests_smoke.html +# +include ::macdefaults diff --git a/manifests/init.pp b/manifests/init.pp index 9a8d946..f34dace 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,35 +1,92 @@ -# Note that type can be one of: -# string, data, int, float, bool, data, array, array-add, dict, dict-add -define mac-defaults($domain, $key, $value = false, $type = "string", $action = "write") { -case $operatingsystem { - Darwin:{ - case $action { - "write": { - exec {"defaults write $domain $key -$type '$value'": - path => "/bin:/usr/bin", - unless => $type ? { - 'bool' => $value ? { - 'TRUE' => "defaults read $domain $key | grep -qx 1", - 'FALSE' => "defaults read $domain $key | grep -qx 0" - }, - default => "defaults read $domain $key | grep -qx $value | sed -e 's/ (.*)/\1/'" - } - } - } - "delete": { - exec {"defaults delete $domain $key": - path => "/bin:/usr/bin", - logoutput => false, - onlyif => "defaults read $domain | grep -q '$key'" - } - } +# Class: macdefaults +# =========================== +# +# Handle macOS `defaults` from Puppet +# +# Parameters +# ---------- +# +# * `ensure` - present or absent +# * `domain` +# * `key` +# * `type` +# * `value` +# +# Examples +# -------- +# +# @example +# macdefaults { "AppleUpdatesThroughMunki": +# ensure => present, +# domain => "/Library/Preferences/ManagedInstalls", +# key => "InstallAppleSoftwareUpdates", +# type => 'bool', +# value => True, +# } +# +# Authors +# ------- +# +# @author Robin Laurén +# +# Based on the works of +# * Will Farrington https://github.com/wfarr/puppet-osx_defaults +# * Graham Gilbert https://github.com/pebbleit/puppet-macdefaults +# +# Copyright +# --------- +# +# Copyright (c) Robin Laurén / Reaktor (c) 2017, All rights reserved. +# License: BSD 2-Clause License (see LICENSE) + +class macdefaults ( + String $ensure = 'present', + String $domain = undef, + String $key = undef, + $value = undef, + String $type = 'string', +) { + + assert_type(Enum['present', 'absent'], $ensure) + assert_type(Enum['string', 'data', 'int', 'integer', 'float', 'bool', 'boolean', 'date', 'array', 'array-add', 'dict', 'dict-add'], $type) + assert_type(String, $domain) + assert_type(String, $key) + + if ($facts['operatingsystem'] != 'Darwin') { + fail('macdefaults only works on macOS') } - } -} + $defaults_cmd = '/usr/bin/defaults' -} + case $ensure { + + 'present': { + if ($value == undef) { + fail ('`value` is missing') + } + + if ($type =~ /^bool(ean)?$/) { + $bvalue = assert_type(Boolean, $value) + $nvalue = bool2num($bvalue) + $value = bool2str($bvalue) + $check = "${defaults_cmd} read ${domain} ${key} -${type} ${value} | grep -qx ${nvalue}" + } else { + $check = "${defaults_cmd} read ${domain} ${key} -${type} | grep -qx ${value}" + } + + exec { "${defaults_cmd} write ${domain} ${key} -${type} ${value}": + unless => $check, + } + } -class macdefaults{ + 'absent': { + exec { "${defaults_cmd} delete ${domain} ${key}": + onlyif => "${defaults_cmd} read ${domain} | egrep '^${key}$''", + } + } + default: { + fail ('macdefaults ensure => [present | absent] domain key type value') + } + } } diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..fc34319 --- /dev/null +++ b/metadata.json @@ -0,0 +1,14 @@ +{ + "name": "llauren-macdefaults", + "version": "0.2.0", + "author": "llauren", + "summary": "Handle MacOS Defaults", + "license": "FreeBSD", + "source": "https://github.com/llauren/puppet-macdefaults", + "project_page": "https://github.com/llauren/puppet-macdefaults", + "issues_url": "https://github.com/llauren/puppet-macdefaults/issues", + "dependencies": [ + {"name":"puppetlabs-stdlib","version_requirement":">= 4.0.0"} + ], + "data_provider": null +}