Pulling Strings With Puppet - James Turnbull [31]
The generate function calls an external command (optionally with arguments) and returns the result to Puppet. You can see a generate function in Listing 3-28.
Listing 3-28. The generate Function
In Listing 3-28, we've defined a variable called $interfaces that calls the generate function. All generate functions must have a command specified, and then any potential arguments are specified after the command, each separated by commas. In Listing 3-28, the result of running the command
would be returned to Puppet and used to populate the $interfaces variable. The command that executes must exit with a return code of o. Any other return code will result in a parse error being generated.
Tip - The generate function will only accept file separators, alphanumeric characters, dashes, and periods. There is some limited protection against malicious calls, but you should be careful when crafting your generate calls.
Qualifying Definitions Using search
The search function allows you to reference definitions contained in other classes without the need to qualify them. Remember how we discussed definition qualification? We discovered that we could refer to a definition defined in another class by specifying the class name and the definition name separated by two colons, ::. The search function allows you to add a "search path" to a class that allows referencing of definitions without qualification, for example:
Here we've defined two classes, rails and webserver, and then created a definition called site in the rails class. We want to refer to this definition in the second class, and so we've added the search function and the name of the class that contains the definition we want to reference, in this case rails. We've then called the site definition.
Tip - If we didn't use the search function, we could still refer to the site definition by using the syntax rails::site.
Using tag and tagged
The next two functions, tag and tagged, can be added to nodes, classes, and definitions to provide another method of classifying them.
Tip - There is a metaparameter, also called tags, that can be used to tag individual resources.
Tagging allows you to group resources together, for example, specifying resources as belonging to a test or development environment. You can add as many tags as you wish.
Note - Like other functions, tags are order dependent and set as resources are evaluated. You can't make use of a tag that has not been set yet.
On the previous lines, we've specified a node definition and used the tag function to add the devel tag. We've then used a conditional if clause and the tagged function. If the devel tag is applied to that node, the dev_test class will be included.
Some tags are automatically created; for example, all resources defined in a class, node, or definition structure will be tagged with the name of that structure. For example, if we define a file resource, /etc/passwd, in a class called basics, this resource would automatically have the tag basics added to it. Another example occurs when a class is included in a node; a tag with the same name as the class will then be set for that node. You can see how this might be useful in Listing 3-29.
In Listing 3-29, we create two nodes, nodes, which includes the webserver and basics classes, and node2, which includes the databaseserver and basics classes.
We then define the basics class. Inside this class we use a combination of the if conditional and the tagged function. In this example, if the node including the basics class is tagged as webserver (which nodes automatically is as a result of including the webserver class), a notice is sent. If the node is tagged with databaseserver (as node2 is automatically), an alternative notice is sent.
Tip - We can obviously do more than send a notice here, like implement a particular resource or load a particular package or packages.
We can also select which configuration is implemented based on tags. We do this in the Puppet configuration file by setting the value of the tags configuration option like so: