Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pkg
pkg
.DS_Store
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 0 additions & 6 deletions Modulefile

This file was deleted.

148 changes: 118 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -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",
}
# 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!
12 changes: 12 additions & 0 deletions examples/init.pp
Original file line number Diff line number Diff line change
@@ -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
115 changes: 86 additions & 29 deletions manifests/init.pp
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
#
# 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')
}
}
}
14 changes: 14 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
@@ -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
}