Using custom functions in Puppet templates

Friday, January 1st, 2010

This eventually required a support ticket to figure out, so I’m documenting it here in case it’s useful to others.

The problem: You have a puppet function you find useful. At this point custom functions are really easy to create and distribute via modules so there’s really no reason not to be using them. However, you want to use the result of a function in your templates.

A real-world example of this is sharing authentication information. (For example, crypted password hashes. Plain text, as always, would be evil no matter where it was living.)
You really have 3 choices:

  • Coding it right into your puppet code and checking that into your version control system
  • Not distributing that information with puppet
  • Using puppet to distribute the information, but store it outside of your puppet modules somehow.

We chose the third way, and store this kind of information in YAML files outside the puppet modules tree.
Anyway. So we want to access this info inside a template.

Assume you have a function called ‘get_extdata’.
You normally call from your ‘.pp’ manifests with something like

$data = get_extdata('mymodule', 'path:to:data')

You can make a call like that from your template by doing this wonderful fragment of magic-wand-waving to get this function accessible:

In mytemplate.erb:

<% Puppet::Parser::Functions.autoloader.loadall %>
Now you can use the 'scope' variable to get at your function.
This is the equivalent of the call get_extdata('mymodule',  'path:to:data'):
<%= scope.function_get_extdata('mymodule',  'path:to:data') %>

This works like a charm, and means you don’t have to create a bunch of variables that you don’t really need before you load the template.

So if you were creating an .htpasswd style file with puppet, you could do

In your init.pp

$users = ['steve', 'paul', 'stu']

htpasswd.erb:

<% Puppet::Parser::Functions.autoloader.loadall %>
<% users.each do |user| -%>
<%= user %>:<%= scope.function_get_extdata('authmodule',  user) %>
<% end -%>

Updated “Inbox Zero with Mail.app” technique

Wednesday, December 2nd, 2009

Back in March, I wrote about my technique for implementing Inbox Zero with Mail.app.

Since then, the world has changed. I’ve upgraded to Snow Leopard, and Quicksilver has essentially stopped working out for me. (I’ve been trying to keep it up to date, and sometimes it kind of works, but my confidence levels are really low.) On the other hand, I’m loving me some Google Quick Search Box (a new project from the original creator of Quicksilver). The only feature that I still wanted Quicksilver for was triggers. And until today, I was still running it for trigger support to implement my Inbox Zero trick.

And then triggers broke when I upgraded it. And I’m out.

So here’s how to get Inbox Zero magic in Mail.app using only tools native to Snow Leopard.

First, launch Automator and create a new Service workflow.
Automator Create a new Service Workflow

Select “Utilities” and then drag in “Run Applescript” to the window on the right.

Automator: Run Applescript

Fill in your applescript, replacing only the center “comment” block — leave the other autogenerated lines there.

The core code again, (tweak to fit your accounts and archive mailbox names)

tell application "Mail"
	set theSelectedMessages to selection
	set myAccount to "zimbra"
	set myMailbox to "Archive"
	repeat with theMessage in theSelectedMessages
		move theMessage to mailbox myMailbox of account myAccount
	end repeat
end tell

It should look something like this:
Automator: Archive Applescript

And that’s it! Save it, and give it a name you’ll remember. (I chose “Archive Selected Mail.”)

Now it’s actually in Mail’s Menu (under ‘Services’) and we can use the built in OSX hotkey support to launch it.

Go to the System Preferences Menu, click “Keyboard Shortcuts”, and add one for the menu item you created. (It needs to be the same exact name you saved your service as.)

Keyboard Shortcuts: Archive Mail

Badda bing. Feature complete, and I can (sadly) retire Quicksilver forever. This technique should be extensible to all kinds of other cases when you want to add new features to applications, for access either through the menus or with hot keys.

Launching new specialized blog: ArduinoCollective.com

Wednesday, November 11th, 2009

My friend Nate and I have launched a new joint blog to record our electronics hacking projects: the Arduino Collective.

Subscribe over there if you’re interested in that kind of thing.