Skip to content
This repository has been archived by the owner on Oct 22, 2019. It is now read-only.

Real time config support #32

Open
wants to merge 85 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
46e9939
Add some basic integration tests using test-kitchen
benlangfeld May 11, 2014
8873d41
Move to a per-suite test manifest layout
benlangfeld May 11, 2014
ee24436
This config is ignored anyway
benlangfeld May 11, 2014
811c010
Test root credentials work and the requested suffix is created
benlangfeld May 11, 2014
1cf1781
Test that a root org can be created at a fresh DIT and then read
benlangfeld May 11, 2014
86f660d
System root user needs management access to new DIT
benlangfeld May 11, 2014
e17a9ef
Bad whitespace
benlangfeld May 12, 2014
ef2e9f5
Lock Ruby version
benlangfeld May 12, 2014
e2d0073
Test coverage for loading of default schema
benlangfeld May 12, 2014
c6dd7a2
Test coverage for loading of non-default, bundled schema
benlangfeld May 12, 2014
6f02843
Test coverage of loaded modules
benlangfeld May 12, 2014
9ef3888
Test coverage for performance tweaks
benlangfeld May 12, 2014
0f511aa
Specs for indices
benlangfeld May 12, 2014
59e3c54
Clearer nesting
benlangfeld May 12, 2014
1c8dba5
Tests for ACLs
benlangfeld May 13, 2014
011d83e
Tests for syncprov
benlangfeld May 13, 2014
f3318aa
Test that TLS config makes it into LDAP
benlangfeld May 14, 2014
9ff46d2
Test TLS connection
benlangfeld May 14, 2014
b625854
Build with puppet debug mode in test-kitchen
benlangfeld May 14, 2014
0b6206c
Add integration tests for slave server
benlangfeld May 14, 2014
5e30e48
Remove unused config
benlangfeld May 14, 2014
09e7434
Use Chef Bento base boxes
benlangfeld May 14, 2014
e03198b
kitchen-puppet contributions got merged
benlangfeld May 14, 2014
ba27f38
Test on Debian and CentOS
benlangfeld May 14, 2014
724413f
Integration tests should take platform differences into account
benlangfeld May 14, 2014
d6cc4cb
Always load back_bdb module
benlangfeld May 14, 2014
eab56fd
Ubuntu 14.04 has problems installing Puppet
benlangfeld May 14, 2014
94f3202
Debian and Ubuntu store certs in the same place
benlangfeld May 14, 2014
547f7af
First pass at running without a config file
benlangfeld May 14, 2014
07ba59c
Absorb ldapdn type/provider for directory manipulation
benlangfeld May 15, 2014
e02d381
Simplification of ldapdn provider
benlangfeld May 15, 2014
0653534
Use ldapdn type for specifying individual config options
benlangfeld May 15, 2014
7df22b3
Database needs to be created to add OUs to it
benlangfeld May 16, 2014
85b1ad0
No need to nuke the database
benlangfeld May 16, 2014
37c8fc1
Dead whitespace
benlangfeld May 17, 2014
853cdf8
Reduce unnecessary indenting
benlangfeld May 17, 2014
024c81c
Initial conversion to direct manipulation of cn=config
benlangfeld May 19, 2014
fb0b3c0
Set log level in dynamic config
benlangfeld May 26, 2014
e956174
Missing specs for slave
benlangfeld May 26, 2014
1b8bdfd
Move PID and args files to dynamic config
benlangfeld May 26, 2014
606f89a
Log level should only have one value
benlangfeld May 26, 2014
2d80400
Fix up slave config
benlangfeld May 26, 2014
f3bf6e6
Don't hard-code indices
benlangfeld May 26, 2014
12b2156
Do away with the last of the server config file
benlangfeld May 27, 2014
1ed9a1a
Fix definition
benlangfeld May 27, 2014
062f4c5
Indices are space sensitive
benlangfeld May 27, 2014
4ef906b
Named this attribute wrong
benlangfeld May 27, 2014
b30c4f8
Resource ordering here was broken
benlangfeld May 27, 2014
ee8df6b
Some OS' only have .schema schemas
benlangfeld May 27, 2014
6d79156
TLS config can only take a single value
benlangfeld May 27, 2014
ce3f037
`tempfile` is not present on CentOS
benlangfeld May 27, 2014
c532a9d
Main DB DN varies between OS'
benlangfeld May 27, 2014
d1023e4
Schema conversion requires the server to be up
benlangfeld May 27, 2014
f686d72
We need to be smarter about managing indices
benlangfeld May 27, 2014
15de2a3
We don't actually care about these values
benlangfeld May 27, 2014
3b82d4c
Runfiles are stored in different places on CentOS
benlangfeld May 27, 2014
eecf77a
Setup the database correctly on CentOS
benlangfeld May 27, 2014
78c0dc6
CentOS doesn't load any modules by default
benlangfeld May 27, 2014
364c78b
Only create one syncprov config instance
benlangfeld May 27, 2014
b04107c
DB Checkpoint isn't always set
benlangfeld May 27, 2014
b31574f
Manage indices as a batch since they can't easily be replaced individ…
benlangfeld May 28, 2014
d70b171
Proper capitalisation
benlangfeld May 28, 2014
18bc068
Ensure that syncprov config can be created cleanly
benlangfeld May 28, 2014
a46dc88
Can't create syncprov config until the plugin is loaded
benlangfeld May 28, 2014
350bfaf
We need to be sure the directory exists
benlangfeld May 28, 2014
d1da8e0
Avoid duplicate resource declaration
benlangfeld May 28, 2014
3554650
Ensure that binding as a normal user works properly
benlangfeld May 28, 2014
88a87d8
Don't hard-code test domain
benlangfeld May 29, 2014
47e3daf
Remove bad spaces
benlangfeld May 29, 2014
7a613ea
Nest some types under server
benlangfeld May 29, 2014
c251e09
Extract common code between master and slave server manifests
benlangfeld May 30, 2014
12a2ea5
Fix a resource name
benlangfeld May 30, 2014
bfcec33
Combine some resources
benlangfeld May 30, 2014
4ec9ace
More robust ordering
benlangfeld May 30, 2014
0938479
Allow management of multiple databases
benlangfeld May 30, 2014
72d9b23
Remove unnecessary symlinks
benlangfeld Jun 2, 2014
ca7dd4d
Set all DB options in a single resource
benlangfeld Jun 5, 2014
7daff68
Properly use specified sync bindDN in ACLs
benlangfeld Jun 6, 2014
626c128
Properly specify overlay order
benlangfeld Jun 6, 2014
d672427
Use HDB by default
benlangfeld Jun 6, 2014
8cb0068
Make sure that server is fully initialised before databases can be cr…
benlangfeld Jun 6, 2014
7e0498a
Don't setup syncprov on a database until the database is configured
benlangfeld Jun 6, 2014
88701a2
Don't try and set a rootpw on a database if none is provided
benlangfeld Jun 6, 2014
35d26c6
Don't create an initial BDB database (overlapping with HDB)
benlangfeld Jun 7, 2014
3a7a24e
Make database data directory configurable
benlangfeld Jun 7, 2014
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.swp
pkg
spec/fixtures
.kitchen/
.kitchen.local.yml
.librarian
.tmp
20 changes: 20 additions & 0 deletions .kitchen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
driver:
name: vagrant

provisioner:
name: puppet_apply
modules_path: ..
fileserver_config_path: puppet/fileserver.conf
files_path: puppet/files
puppet_debug: true

platforms:
- name: debian-6.0.8
- name: debian-7.2.0
- name: ubuntu-12.04
- name: centos-6.4

suites:
- name: master
- name: slave
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.0.0-p451
11 changes: 9 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
source :rubygems
source 'https://rubygems.org'

ruby '2.0.0'

gem 'rake', '~> 0.8.7'
gem 'puppet', '~> 2.7'
gem 'puppet', '~> 3.0'
gem 'rspec-puppet', '~> 0.1.6'
gem 'puppetlabs_spec_helper', '~> 0.4.1'

gem 'test-kitchen', '~> 1.0'
gem 'kitchen-vagrant'
gem 'kitchen-puppet', github: 'neillturner/kitchen-puppet', branch: 'master'
gem 'librarian-puppet'
48 changes: 44 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
GIT
remote: git://github.com/neillturner/kitchen-puppet.git
revision: b8e7579962629b9b3c110d4569da0031a12df47d
branch: master
specs:
kitchen-puppet (0.0.9)

GEM
remote: http://rubygems.org/
remote: https://rubygems.org/
specs:
diff-lcs (1.2.4)
facter (1.7.2)
hiera (1.3.2)
json_pure
highline (1.6.21)
json (1.8.1)
json_pure (1.8.0)
kitchen-vagrant (0.15.0)
test-kitchen (~> 1.0)
librarian (0.1.2)
highline
thor (~> 0.15)
librarian-puppet (1.0.2)
json
librarian (>= 0.1.2)
metaclass (0.0.1)
mixlib-shellout (1.4.0)
mocha (0.14.0)
metaclass (~> 0.0.1)
puppet (2.7.22)
facter (~> 1.5)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.0)
puppet (3.5.1)
facter (> 1.6, < 3)
hiera (~> 1.0)
json_pure
rgen (~> 0.6.5)
puppetlabs_spec_helper (0.4.1)
mocha (>= 0.10.5)
rake
rspec (>= 2.9.0)
rspec-puppet (>= 0.1.1)
rake (0.8.7)
rgen (0.6.6)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
Expand All @@ -24,12 +52,24 @@ GEM
rspec-mocks (2.13.1)
rspec-puppet (0.1.6)
rspec
safe_yaml (1.0.3)
test-kitchen (1.2.1)
mixlib-shellout (~> 1.2)
net-scp (~> 1.1)
net-ssh (~> 2.7)
safe_yaml (~> 1.0)
thor (~> 0.18)
thor (0.19.1)

PLATFORMS
ruby

DEPENDENCIES
puppet (~> 2.7)
kitchen-puppet!
kitchen-vagrant
librarian-puppet
puppet (~> 3.0)
puppetlabs_spec_helper (~> 0.4.1)
rake (~> 0.8.7)
rspec-puppet (~> 0.1.6)
test-kitchen (~> 1.0)
3 changes: 0 additions & 3 deletions Modulefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,3 @@ license 'GPL v2'
summary 'OpenLDAP module for Puppet.'
description 'Manage OpenLDAP clients and server via Puppet'
project_page 'https://github.com/torian/puppet-ldap'

# Dependency
dependency 'puppetlabs/stdlib', '>= 4.1.0'
3 changes: 3 additions & 0 deletions Puppetfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
forge "https://forge.puppetlabs.com"

modulefile
2 changes: 2 additions & 0 deletions Puppetfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DEPENDENCIES

99 changes: 99 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,99 @@ Configure an OpenLdap slave:
],
}

### Directory updates

This module includes a puppet type and provider that aims to simply managing ldap entries via ldapmodify and ldapadd commands.

In essence the mechanism it uses is described as follows:

* Translate the puppet "ldapdn" resource into an in-memory ldif
* ldapsearch the existing dn to verify the current contents (if any)
* compare the results of the search with what should be the case
* work out which add/modify/delete commands are required to get to the desired state
* write out an appropriate ldif file
* execute it via an ldapmodify statement.

Examples of usage are as follows:

First you might like to set a root password:

```puppet
ldapdn { "add manager password":
dn => "olcDatabase={2}hdb,cn=config",
attributes => ["olcRootPW: password"],
unique_attributes => ["olcRootPW"],
ensure => present,
}
```

`attributes` sets the attributes that you wish to set (be sure to separate key and value with <semi-colon space>).
`unique_attributes` can be used to specify the behaviour of `ldapmodify` when there is an existing attribute with this name. If the attribute key is specified here, then `ldapmodify` will issue a replace, replacing the existing value (if any), whereas if the attribute key is not specified here, then `ldapmodify` will simply ensure the attribute exists with the value required, alongside other values if also specified (e.g. for `objectClass`).

```puppet
$organizational_units = ["Groups", "People", "Programs"]
ldap::add_organizational_unit { $organizational_units: }

define ldap::add_organizational_unit () {
ldapdn { "ou ${name}":
dn => "ou=${name},dc=example,dc=com",
attributes => [ "ou: ${name}",
"objectClass: organizationalUnit" ],
unique_attributes => ["ou"],
ensure => present,
}
}
```

In the above example, multiple groups are created. Notice in each case, that `objectClass` does not form part of the `unique_attributes`, so that (in future) more `objectClasses` may be added to each ou, without them being replaced.

By default, all ldap commands are issued with the `-QY EXTERNAL` SASL auth mechanism.

Here is how you can create a database in the first place:

```puppet
ldapdn { "add database":
dn => "dc=example,dc=com",
attributes => ["dc: example",
"objectClass: top",
"objectClass: dcObject",
"objectClass: organization",
"o: example.com"],
unique_attributes => ["dc", "o"],
ensure => present
}
```

Additionally, you may need to specify alternative authentication options when managing resources:

```puppet
ldapdn { "add database":
dn => "dc=example,dc=com",
attributes => ["dc: example",
"objectClass: top",
"objectClass: dcObject",
"objectClass: organization",
"o: example.com"],
unique_attributes => ["dc", "o"],
ensure => present,
auth_opts => ["-xD", "cn=admin,dc=example,dc=com", "-w", "somePassword"],
}
```

Sometimes you will want to ensure an attribute exists, but wont care about its subsequent value. An example of this is a password.

```puppet
ldapdn { "add password":
dn => "cn=Geoff,ou=Staff,dc=example,dc=com",
attributes => ["olcUserPassword: {SSHA}somehash..."],
unique_attributes => ["olcUserPassword"],
indifferent_attributes => ["olcUserPassword"],
ensure => present
}
```

By specifying `indifferent_attributes, ensure => present` will ensure that if the key doesn't exist, it will create it with the desired password hash, but if the key does exist, it won't bother replacing it again. In this way you can keep passwords managed by something like phpldapadmin if you so wish.

Notes
-----

Expand Down Expand Up @@ -136,6 +229,12 @@ Requirements
* If enable_motd is enabled (enable_motd => true) you'll need
[puppet-motd](https://github.com/torian/puppet-motd.git)

Testing
-------

Unit tests: `rake spec`
Integration tests: `kitchen test`

TODO
----

Expand Down
87 changes: 87 additions & 0 deletions files/convertschema.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/sh

# Script to convert schema files to LDIF files
#
# OPTIONS:
# -s The input schema file to convert
# -l The resulting LDIF file
# -d A comma separated list of schema dependencies
# -sd The schema directory
#

SCHEMAFILE=""
LDIFFILE=""
DEPS=""
SCHEMADIR=""

while getopts "s:l:d:sd:" options; do
case $options in
s ) SCHEMAFILE=$OPTARG;;
l ) LDIFFILE=$OPTARG;;
d ) DEPS=$OPTARG;;
sd ) SCHEMADIR=$OPTARG;;
* ) echo "Specify input schema file with -s and output LDIF file with -l"
exit 1;;
esac
done

# do we have -s?
if [ x${SCHEMAFILE} = "x" ]; then
echo "Please specify a input schema file with -s"
exit 1
fi

# do we have -l?
if [ x${LDIFFILE} = "x" ]; then
echo "Please specify an output LDIF file with -l"
exit 1
fi

# can we write to -l?
if [ -f ${LDIFFILE} ]; then
if [ ! -w ${LDIFFILE} ]; then
echo "Cannot write to ${LDIFFILE}"
exit 1
fi
else
if [ ! -w `dirname ${LDIFFILE}` ]; then
echo "Cannot write to `dirname ${LDIFFILE}` to create ${LDIFFILE}"
exit 1
fi
fi

# do we have -sd?
if [ x${SCHEMADIR} = "x" ]; then
SCHEMADIR=/etc/ldap/schema
fi

# Get the base name of the schema file
BASENAME=`basename ${SCHEMAFILE} | cut -d'.' -f1`

# Create a temporary config file and directory to set the schemas to process
TEMPDIR=$(mktemp -d) || exit 1
TEMPFILE=$(mktemp -p ${TEMPDIR}) || exit 1

# Add all of the dependencies
for dep in `echo ${DEPS} | sed s/,/\\\n/g`; do
if [ -f "${SCHEMADIR}/${dep}.schema" ]; then
echo "include ${SCHEMADIR}/${dep}.schema" >> ${TEMPFILE}
fi
done
echo "include ${SCHEMAFILE}" >> ${TEMPFILE}

# Determine the index of the schema
SCHEMAINDEX=$(slapcat -f ${TEMPFILE} -F ${TEMPDIR} -n 0 | grep "${BASENAME},cn=schema")
SCHEMADN=$(echo "${SCHEMAINDEX}" | sed 's/dn: //g')

# Convert the schema to LDIF format
slapcat -f ${TEMPFILE} -F ${TEMPDIR} -n 0 -H ldap:///${SCHEMADN} -l ${TEMPDIR}/cn=${BASENAME}.ldif || exit 1

# Remove index information
sed -e "s/{[0-9]*}${BASENAME}/${BASENAME}/g" \
-e "/^structuralObjectClass:/d; /^entryUUID:/d; /^creatorsName:/d; /^createTimestamp:/d" \
-e "/^entryCSN:/d; /^modifiersName:/d; /^creatorsName:/d; /^modifyTimestamp:/d" \
${TEMPDIR}/cn=${BASENAME}.ldif > ${LDIFFILE}

# Cleanup resources
rm -rf -- "${TEMPDIR}"
Loading