Pulling Strings With Puppet - James Turnbull [53]
In Listing 7-7, you can also see that we've added something to our shell parameter, isnamevar, that tells Puppet that this parameter is the attribute that sets the title or name of our type. Each type needs to have a parameter that is the name variable. In the Type Reference Wiki page (http://reductivelabs.com/trac/puppet/wiki/TypeReference),you can see that each type has a name variable defined.
Tip - Both properties and parameters can have the desc method. This is used to document each property or parameter. You should always use the desc method to document your resource type and assist others in understanding what each property and parameter does.
Creating Our Provider
Once we've created our type, we are going to create a simple provider to perform the changes defined in our type on the /etc/shells file. Providers that make use of the ParsedFile class should be stored in a directory named after the type and stored in a file called parsed.rb, for example, /var/puppet/lib/providers/shells/parsed.rb. You can see that provider in Listing 7-8.
The first line in Listing 7-8 is a require for the ParsedFile class we discussed in the type section. The ParsedFile is a helper class that can help you manage text-based configuration files. It contains a number of simple functions to parse, edit, and update files. For most of your configuration files, this simple class will probably provide most of the required functionality to manage them.
Tip - I recommend taking a close look at the class contained in the parsedfile. rb file located in your puppet/provider directory. It has a number of useful features and examples.
Next in Listing 7-8 we've specified the default location of our /etc/shells file. We're going to make use of this variable later in our provider.
Then we define the framework for our provider itself. You can see that we've named it shells.
We define the ParsedFile class as a parent of the provider to enable its functionality and specify some values from the class: the default_target value and the file type of the configuration file we're going to manipulate, in our case a flat file. The default_target value makes use of the variable we defined earlier with the default location of the /etc/shells file. We could override this value by setting the target attribute in our resource.
We also call desc to document our provider.
Next, we specify a confine helper method, which tells Puppet to only use the provider if the /etc/shells file exists. A number of these helper methods exist to assist in developing and configuring your providers. The confine helper method, together with another related helper method, commands, determines where the provider is suitable. You can test for a particular file, or a command, using Facter facts or whether a given value is true or false. For example, to make our provider suitable only for a particular operating system, we could use
The commands helper method is similar to a confine except that it tells Puppet that a particular binary must be present for the provider to be suitable.
If you have multiple providers, it is also possible to define a default provider for a particular fact or set of facts. This assists in hiding implementation details from users and allows them to focus on configuring their resource. For example, to declare a provider as the default provider for all Red Hat hosts, you would use the default-For helper method like so:
After our helper method, we've defined some functions of the ParsedFile. First, we've told Puppet how to identify blank and comment lines in our file using regular expressions. These regular expressions allow ParsedFile to process these lines in our file.
Lastly, the record_line function is the line that actually adds or removes