Now that we can install our OpenLDAP server and ensure that it is running, we want to be able to manage OpenLDAP databases.
For that, we will create an OpenLDAP Puppet type and a provider to manage databases using OpenLDAP’s live configuration API. We will do all this using TDD, of course!
Write the acceptance tests
First, let’s create an acceptance test in
spec/acceptance/openldap_database_spec.rb for our new type “openldap_database”
Write the custom type
Let’s write a custom Puppet type that has these properties:
- is ensurable
- has suffix as namevar
- has backend and directory properties
Write the unit tests for the openldap_database type
Unit tests for Puppet types live in spec/unit/puppet/type, so let’s create this directory first.
Then we can create our unit tests for our openldap_database type in
The first thing to do is to require our
First, let’s validate the attributes of our custom type. We have to be sure that it accepts
provider parameters and
Loop over all supported operating systems (in metadata.json)
Create a new rspec context for the operating system currently being tested
Line 7 – 11:
Stub all facts before each test
Lines 14 – 18:
Loop over each desired parameter and validate it
Line 19 – 23:
Loop over each desired property and validate it
Let’s also make sure that
suffix is the namevar of our type:
Write the openldap_database type
The puppet custom types live in lib/puppet/type, so let’s create this directory first:
We can then write our puppet type to manage OpenLDAP databases in
Now let’s validate the attributes value.
We want to ensure that
absent and that
backend matches either
hdb (the 2 current supported OpenLDAP database backends) and defaults to
And now we can adapt our custom type:
And launch the unit tests again:
We should ideally validate more things:
the suffix should be
the directory should be an absolute path
…but this will be left as an exercise for you.
Write the custom provider for openldap_database type
Now let’s write a provider for our custom type. As said, we will use the OpenLDAP configuration API to manage the databases. So we’ll use
slapcat to read the configuration and
ldapmodify to update it. Since we’ll not have a real OpenLDAP server running on our workstation where we run the tests, we’ll have to mock the commands.
Let’s start, as usual, by writing the unit tests.
Write the unit test for the openldap_database’s olc provider
Unit tests for providers lives in
spec/unit/puppet/provider/<type>, so let’s create this directory first:
Next, we can create the unit tests for openldap_database’s olc provider in
Again, the first thing to do is to require our
The first thing we want to do is to list the current instances of the OpenLDAP databases and use this list as a prefetch cache for the resources. So our provider must respond to the
Write the openldap_database’s olc provider
The puppet providers for the
openldap_database type lives in
lib/puppet/provider/openldap_database, so let’s create this directory first:
Then we can create the
olc provider for the
openldap_database type in
lib/puppet/provider/openldap_database/olc.rb with a
self.instances and a
self.prefetch methods plus some things we’ll need:
Declares commands we will use (used by confinement) and creates helper methods dynamically for each command.
Creates accessors (getters and setters) for each property using the @property_hash instance variable created by the
Line 13 – 15:
exists? method which returns a boolean base on whether the ressource is prefetch.
And let’s test:
Write the unit tests for the self.instances method
Now that everything is set up, let’s write the next unit test. We want to make sure that the
self.instances method returns the right resources:
We’ll test with no database:
Then, with one database:
And finally with two databases:
If you launch the unit tests now, it will obviously fails because
nil and we try to call the
size method on it.
Write the provider’s self.instances method
Let’s write the provider code that populates the instances Array:
And if we test now:
Now that we have the
self.instances method, we want to be able to create a database. We will now code the
self.prefetch method, to pass the discovered instances to the catalog resources.
The prefetch method
The prefetch method is used to build a cache of the resources which can be used to easily assert the existence and synchronisation state of the resource, using the @property_hash instance variable.
The method takes a list of catalog resources as argument, and is expected to associate RAL resources to each of them, if they already exist.
Retrieve all the discovered resources from the
self.instances method. This is the most common way to prefetch resources when resources can all be automatically discovered by
For each catalog resource passed to the method, look into the discovered instances to find a RAL resource with a matching name.
If a matching resource is found, associate it to the catalog resource. This will set the values of the
@property_hash instance variable for this resource based on the values set in the
self.instances method for this resource.
The unit test for the create method
Now let’s check that, when we want to create a resource, it generates a valid ldif and that the resource exists. In
The create method
Finally, let’s run the acceptance test to see if it really works.
On RedHat 7
Yes, it does!
On Debian 7
Now that we have a functional type and provider to manage an OpenLDAP database, we will create a function to manage the database’s Root Password in the coming part IV.