Version information
This version is compatible with:
- Puppet 3.x
- , , , , ,
Start using this module
Add this module to your Puppetfile:
mod 'bodgit-openldap', '1.0.0'
Learn more about managing modules with a PuppetfileDocumentation
openldap
Tested with Travis CI
Table of Contents
- Overview
- Module Description - What the module does and why it is useful
- Setup - The basics of getting started with openldap
- Usage - Configuration options and additional functionality
- Reference - An under-the-hood peek at what the module is doing and how
- Limitations - OS compatibility, etc.
- Development - Guide for contributing to the module
Overview
This module manages OpenLDAP.
Module Description
This module can install LDAP libraries, client utilities and more importantly
install and configure the slapd
ḋaemon to provide directory services.
Setup
What openldap affects
- The package(s) providing LDAP support.
- Managing the global and any per-user LDAP client configuration.
- Installing client utilities.
- Installing and configuring the
slapd
daemon. - The service controlling the
slapd
daemon.
Beginning with openldap
include ::openldap
Usage
Classes and Defined Types
Class: openldap
Parameters within openldap
:
package_name
The name of the package to install that provides the LDAP libraries.
conf_dir
The base configuration directory, usually /etc/openldap
or /etc/ldap
.
ldap_conf_file
The global configuration file, normally ${conf_dir}/ldap.conf
.
base
See the base
parameter in openldap::configuration
.
uri
See the uri
parameter in openldap::configuration
.
deref
See the deref
parameter in openldap::configuration
.
network_timeout
See the network_timeout
parameter in openldap::configuration
.
referrals
See the referrals
parameter in openldap::configuration
.
sizelimit
See the sizelimit
parameter in openldap::configuration
.
timelimit
See the timelimit
parameter in openldap::configuration
.
timeout
See the timeout
parameter in openldap::configuration
.
sasl_secprops
See the sasl_secprops
parameter in openldap::configuration
.
sasl_nocanon
See the sasl_nocanon
parameter in openldap::configuration
.
gssapi_sign
See the gssapi_sign
parameter in openldap::configuration
.
gssapi_encrypt
See the gssapi_encrypt
parameter in openldap::configuration
.
gssapi_allow_remote_principal
See the gssapi_allow_remote_principal
parameter in openldap::configuration
.
tls_cacert
See the tls_cacert
parameter in openldap::configuration
.
tls_cacertdir
See the tls_cacertdir
parameter in openldap::configuration
.
tls_cipher_suite
See the tls_cipher_suite
parameter in openldap::configuration
.
tls_protocol_min
See the tls_protocol_min
parameter in openldap::configuration
.
tls_randfile
See the tls_randfile
parameter in openldap::configuration
.
tls_reqcert
See the tls_reqcert
parameter in openldap::configuration
.
tls_crlcheck
See the tls_crlcheck
parameter in openldap::configuration
.
tls_crlfile
See the tls_crlfile
parameter in openldap::configuration
.
Class: openldap::client
Parameters within openldap::client
:
package_name
The name of the package to install that provides the LDAP client utilities.
Class: openldap::server
Parameters within openldap::server
:
root_dn
The Root Distinguished Name used to administer the database.
root_password
The password for the Root Distinguished Name.
suffix
The suffix for the main database.
access
An array of ACLs to apply to the database, in the same form as the olcAccess
attribute.
Do not include an ACL for the DN used by replication, one is added
automatically when the syncprov
parameter is used.
accesslog
Setting this to true
will enable the accesslog
overlay in conjunction
with the syncprov
overlay to enable delta replication.
It will create a separate database with the suffix cn=log
and use the value
of the replica_dn
parameter much like the syncprov
setting to allow it to
be accessed by consumers.
args_file
Where slapd
writes out its command-line arguments.
backend_modules
An array of database backends that are built as modules and therefore require loading before use.
data_directory
The base directory used for database storage. Rather than store one database at the top level, this module creates a sub-directory per-database. Any unmanaged files in the top-level directory will be purged.
db_backend
The chosen database backend, usually one of hdb
, bdb
, or mdb
.
group
The group that runs the slapd
process.
indices
An array of index definitions in the same form as the olcDbIndex
attribute.
Do not include an index for the attributes applicable to the syncprov
overlay. They are added automatically.
ldap_interfaces
Any array of address(:port)
values that will be wrapped with ldap://
&
/
to form a list of interfaces to listen on for regular LDAP (optionally
with STARTTLS) connections, traditionally on TCP port 389.
ldaps_interfaces
Any array of address(:port)
values that will be wrapped with ldaps://
&
/
to form a list of interfaces to listen on for LDAP over SSL connections,
traditionally on TCP port 636.
limits
An array of limits in the same form as the olcLimits
attribute.
Do not include a limit for the DN used by replication, one is added
automatically when the syncprov
parameter is used.
local_ssf
Security strength factor assigned to ldapi
connections.
module_extension
The extension module files have, normally .la
.
package_name
The name of the package to install that provides the LDAP client utilities.
pid_file
Where slapd
writes out its PID.
replica_dn
The Distinguished Name used by consumer/slave servers to connect to this server in order to replicate content.
schema_dir
The base directory used to store the schemas shipped with OpenLDAP. This is
used as a default by the
openldap::server::schema
defined type.
security
Specify minimum security strength factors in the same form as the
olcSecurity
attribute.
ssl_ca
Maps to the olcTLSCACertificateFile
attribute.
ssl_cert
Maps to the olcTLSCACertificatePath
attribute.
ssl_certs_dir
Maps to the olcTLSCertificateFile
attribute.
ssl_cipher
Maps to the olcTLSCipherSuite
attribute.
ssl_dhparam
Maps to the olcTLSDHParamFile
attribute.
ssl_key
Maps to the olcTLSCertificateKeyFile
attribute.
ssl_protocol
Maps to the olcTLSProtocolMin
attribute.
syncprov
Setting this to true
will enable the syncprov
overlay on the main database
allowing consumer/slave servers to replicate the content.
An additional index entryCSN,entryUUID eq
will be appended to those passed
by the indices
parameter.
The value of the replica_dn
parameter is also used to prepend the ACL to * by dn.exact="${replica_dn}" read by * break
to those passed by the access
parameter to allow the consumers to read all of the data. The limit
dn.exact="${replica_dn}" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
is also prepended to any limits passed
with the limits
parameter.
syncprov_checkpoint
Maps to the olcSpCheckpoint
attribute.
syncprov_sessionlog
Maps to the olcSpSessionlog
attribute.
syncrepl
An array of olcSyncrepl
attribute values used to establish a replication
relationship between this server and a producer.
update_ref
An array of referral URIs to return for referring writes from a read-only replica server to the original producer/master server.
user
The user that runs the slapd
process.
Defined Type: openldap::configuration
Parameters within openldap::configuration
:
name
Path to the file
resource.
ensure
Same as a file
resource, i.e. present
, absent
or file
.
owner
Same as a file
resource.
group
Same as a file
resource.
mode
Same as a file
resource.
base
Maps to the BASE
ldap.conf
option.
uri
Maps to the URI
ldap.conf
option.
binddn
Maps to the BINDDN
ldap.conf
option.
deref
Maps to the DEREF
ldap.conf
option.
network_timeout
Maps to the NETWORK_TIMEOUT
ldap.conf
option.
referrals
Maps to the REFERRALS
ldap.conf
option.
sizelimit
Maps to the SIZELIMIT
ldap.conf
option.
timelimit
Maps to the TIMELIMIT
ldap.conf
option.
timeout
Maps to the TIMEOUT
ldap.conf
option.
sasl_mech
Maps to the SASL_MECH
ldap.conf
option.
sasl_realm
Maps to the SASL_REALM
ldap.conf
option.
sasl_authcid
Maps to the SASL_AUTHCID
ldap.conf
option.
sasl_authzid
Maps to the SASL_AUTHZID
ldap.conf
option.
sasl_secprops
Maps to the SASL_SECPROPS
ldap.conf
option.
sasl_nocanon
Maps to the SASL_NOCANON
ldap.conf
option.
gssapi_sign
Maps to the GSSAPI_SIGN
ldap.conf
option.
gssapi_encrypt
Maps to the GSSAPI_ENCRYPT
ldap.conf
option.
gssapi_allow_remote_principal
Maps to the GSSAPI_ALLOW_REMOTE_PRINCIPAL
ldap.conf
option.
tls_cacert
Maps to the TLS_CACERT
ldap.conf
option.
tls_cacertdir
Maps to the TLS_CACERTDIR
ldap.conf
option.
tls_cert
Maps to the TLS_CERT
ldap.conf
option.
tls_key
Maps to the TLS_KEY
ldap.conf
option.
tls_cipher_suite
Maps to the TLS_CIPHER_SUITE
ldap.conf
option.
tls_protocol_min
Maps to the TLS_PROTOCOL_MIN
ldap.conf
option.
tls_randfile
Maps to the TLS_RANDFILE
ldap.conf
option.
tls_reqcert
Maps to the TLS_REQCERT
ldap.conf
option.
tls_crlcheck
Maps to the TLS_CRLCHECK
ldap.conf
option.
tls_crlfile
Maps to the TLS_CRLFILE
ldap.conf
option.
Defined Type: openldap::server::schema
Parameters within openldap::server::schema
:
name
The Common Name of the schema, i.e. core
, inetorgperson
, etc.
position
Position of schema in the list. This maps to the DN of the schema object, i.e.
cn={${position}}${name},cn=schema
.
This module always loads the core
schema at position 0 so this should be
from 1 onwards with no gaps.
attributes
Hash of additional attributes, defaults to {}
.
ldif
LDIF file containing the schema, if not set will default to
${schema_dir}/${name}.ldif
which handles any schema shipped with OpenLDAP.
See the openldap
type.
purge
Defaults to false
, see the openldap
type.
Native Types
Native Type: openldap
openldap { 'cn=schema,cn=config':
ensure => present,
attributes => {
'cn' => 'schema',
'objectClass' => 'olcSchemaConfig',
},
}
This type autorequires parent objects, (Openldap['cn=config'] -> Openldap['cn=schema,cn=config']
), as well as siblings if they use the OpenLDAP
positional syntax, (Openldap['olcDatabase={0}config,cn=config'] -> Openldap['olcDatabase={1}monitor,cn=config']
). Other relationships should
be explicitly declared if certain objects are required to exist before others.
Parameters within openldap
:
ensure
Standard ensurable parameter. Be aware that quite a lot of OpenLDAP configuration settings are additive and that the server will be "unwilling to perform" deletion. For example dynamic modules can be loaded, but cannot be unloaded again.
attributes
Hash of object attributes 'name' => 'value'
. In the case of multiple values,
use an array of values 'name' => ['value1', 'value2']
.
If a file resource exists in the catalogue for any value of a known set of
attributes, (olcDbDirectory
, olcTLSCertificateFile
, etc.), then it will be
autorequired.
purge
Controls purging of unknown attributes and/or values. Defaults to true
to
purge anything not explicitly declared but can also be set to false
so that
only missing attributes are added, or partial
which purges any unknown
attribute values for explcitly declared attributes, but will leave alone any
attributes not declared.
ldif
Path to LDIF file containing the object definition which is used only if the object does not exist yet, (This is a shortcut for loading huge schema files without duplicating the whole schema object in the catalogue).
If a file resource exists in the catalogue for this value it will be autorequired.
service
The name of the service controlling the slapd
daemon. In order to affect
change the daemon needs to be running first. The service resource will be
autorequired.
Examples
Install the LDAP libraries and create a global ldap.conf
mimicking the stock
RHEL/CentOS install as well as a per-user .ldaprc
for any subsequently
created users. Also install the client utilities:
class { '::openldap':
tls_cacertdir => '/etc/openldap/certs'
}
::openldap::configuration { '/etc/skel/.ldaprc':
ensure => file,
owner => 0,
group => 0,
mode => '0640',
base => 'dc=example,dc=com',
uri => 'ldap://ldap.example.com/',
}
::Openldap::Configuration['/etc/skel/.ldaprc'] -> User <||>
include ::openldap::client
Create a standalone directory server listening on the standard LDAP TCP port 389 that disallows anonymous reads and allows users to update their own object:
include ::openldap
include ::openldap::client
class { '::openldap::server':
root_dn => 'cn=Manager,dc=example,dc=com',
root_password => '{SSHA}7dSAJPGe4YKKEvUPuGJIeSL/03GV2IMY',
suffix => 'dc=example,dc=com',
access => [
'to attrs=userPassword by self =xw by anonymous auth',
'to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by self write by users read',
],
indices => [
'objectClass eq,pres',
'ou,cn,mail,surname,givenname eq,pres,sub',
],
ldap_interfaces => [$ipaddress],
}
::openldap::server::schema { 'cosine':
position => 1,
}
::openldap::server::schema { 'inetorgperson':
position => 2,
}
::openldap::server::schema { 'nis':
position => 3,
}
Extend the above example to become a producer/master server for a number of consumer/slave servers:
include ::openldap
include ::openldap::client
class { '::openldap::server':
root_dn => 'cn=Manager,dc=example,dc=com',
root_password => '{SSHA}7dSAJPGe4YKKEvUPuGJIeSL/03GV2IMY',
suffix => 'dc=example,dc=com',
access => [
'to attrs=userPassword by self =xw by anonymous auth',
'to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by self write by users read',
],
indices => [
'objectClass eq,pres',
'ou,cn,mail,surname,givenname eq,pres,sub',
],
ldap_interfaces => [$ipaddress],
replica_dn => 'cn=replicator,dc=example,dc=com',
syncprov => true,
}
::openldap::server::schema { 'cosine':
position => 1,
}
::openldap::server::schema { 'inetorgperson':
position => 2,
}
::openldap::server::schema { 'nis':
position => 3,
}
Extend this further to also enable delta replication:
include ::openldap
include ::openldap::client
class { '::openldap::server':
root_dn => 'cn=Manager,dc=example,dc=com',
root_password => '{SSHA}7dSAJPGe4YKKEvUPuGJIeSL/03GV2IMY',
suffix => 'dc=example,dc=com',
access => [
'to attrs=userPassword by self =xw by anonymous auth',
'to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by self write by users read',
],
accesslog => true,
indices => [
'objectClass eq,pres',
'ou,cn,mail,surname,givenname eq,pres,sub',
],
ldap_interfaces => [$ipaddress],
replica_dn => 'cn=replicator,dc=example,dc=com',
syncprov => true,
}
::openldap::server::schema { 'cosine':
position => 1,
}
::openldap::server::schema { 'inetorgperson':
position => 2,
}
::openldap::server::schema { 'nis':
position => 3,
}
Create a server acting as a consumer of another server using delta replication and pass back a referral to clients on attempting to write:
include ::openldap
include ::openldap::client
class { '::openldap::server':
root_dn => 'cn=Manager,dc=example,dc=com',
root_password => '{SSHA}7dSAJPGe4YKKEvUPuGJIeSL/03GV2IMY',
suffix => 'dc=example,dc=com',
access => [
'to attrs=userPassword by self =xw by anonymous auth',
'to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by self write by users read',
],
indices => [
'objectClass eq,pres',
'ou,cn,mail,surname,givenname eq,pres,sub',
],
ldap_interfaces => [$ipaddress],
syncrepl => [
'rid=001 provider=ldap://ldap.example.com/ searchbase="dc=example,dc=com" bindmethod=simple binddn="cn=replicator,dc=example,dc=com" credentials=secret logbase="cn=log" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog',
],
update_ref => 'ldap://ldap.example.com/',
}
::openldap::server::schema { 'cosine':
position => 1,
}
::openldap::server::schema { 'inetorgperson':
position => 2,
}
::openldap::server::schema { 'nis':
position => 3,
}
Reference
Classes
Public Classes
openldap
: Main class for installing base LDAP library.openldap::client
: Main class for installing LDAP client utilities.openldap::server
: Main class for installing and managingslapd
daemon.
Private Classes
openldap::config
: Handles base LDAP library configuration.openldap::install
: Handles base LDAP library installation.openldap::params
: Different configuration data for different systems.openldap::client::install
: Handles LDAP client utility installation.openldap::server::config
: Handlesslapd
configuration.openldap::server::install
: Handlesslapd
installation.openldap::server::service
: Handles starting theslapd
daemon.
Defined Types
Public Defined Types
openldap::configuration
: Handles creating global or per-user LDAP client configuration.openldap::server::schema
: Installs and enables LDAP schemas inslapd
.
Native Types
openldap
: Manages a configuration object in theslapd
OLC (cn=config
) DIT.
Limitations
Rather than expose overlays, modules, databases, etc. as defined or native types and leave the user to build their own configuration this module takes the decision to hide most of this complexity and build what most people probably want out of OpenLDAP; a single database, possibly replicated. This is largely due to a number of behaviours and idiosyncrasies of OpenLDAP; the order of overlays matters for example.
As alluded to by the openldap
native type, a lot of
attributes or objects are additive and can't be deleted without manually
editing the configuration. This module will always try and issue the necessary
LDIF commands however the server will be "unwilling to perform" them. This
means that if you try to convert from say a replicating producer back to a
standalone server you will probably get errors from trying to remove the
various replication objects. However things should always build from scratch
cleanly.
This module has been built on and tested against Puppet 3.0 and higher.
The module has been tested on:
- RedHat/CentOS Enterprise Linux 6/7
- Ubuntu 12.04/14.04
- Debian 6/7
It should also probably work on:
- Fedora 19/20 (need vagrant boxes for tests)
Testing on other platforms has been light and cannot be guaranteed.
Development
Please log issues or pull requests at github.
Types in this module release
Dependencies
- puppetlabs/stdlib (>=4.6.0 <5.0.0)
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2013 Puppet Labs Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.