Changeset - 9f804c9501da
[Not reviewed]
0 4 0
Branko Majic (branko) - 9 years ago 2015-10-14 18:15:06
branko@majic.rs
MAR-39: Added support for specifying consumers of LDAP structure to the LDAP server role. Added support to the LDAP server role for specifying groups to create. Modified the ldap_entry implementation, replacing the addattributes/replaceattributes with append/replace states. The new states allow for creation of entry if it does not exist, making them more versatille. The existing classes and configurations have been updated accordingly.
4 files changed with 104 insertions and 77 deletions:
0 comments (0 inline, 0 general)
roles/ldap_server/defaults/main.yml
Show inline comments
 
@@ -9,6 +9,8 @@ ldap_server_log_level: 256
 
ldap_server_tls_certificate: "{{ tls_certificate_dir }}/{{ ansible_fqdn }}_ldap.pem"
 
ldap_server_tls_key: "{{ tls_private_key_dir }}/{{ ansible_fqdn }}_ldap.key"
 
ldap_server_ssf: 128
 
ldap_server_consumers: []
 
ldap_server_groups: []
 
ldap_permissions:
 
  - >
 
    to *
roles/ldap_server/library/ldap_entry.py
Show inline comments
 
@@ -22,12 +22,13 @@ options:
 
  state:
 
    description:
 
      - LDAP entry state. State C(present) requires that all entry attributes
 
        are listed. If you wish to add some attributes, with specific values, to
 
        existing entry, use state C(addattributes). If you wish to replace
 
        existing values for an attribute, use C(replaceattributes).
 
        are listed. If you wish to append attributes to existing entry (or
 
        create a new one if it does not exist) use state C(append). If
 
        you wish to replace existing values for an attribute or create a new
 
        entry if it does not exist, use C(replace).
 
    required: true
 
    default: "present"
 
    choices: [ "present", "absent", "addattributes", "replaceattributes" ]
 
    choices: [ "present", "absent", "append", "replace" ]
 
  server_uri:
 
    description:
 
      - LDAP connection URI specifying what server to connect to.
 
@@ -55,7 +56,7 @@ options:
 
        C(base64:) (this is useful for I(usercertificate;binary) or
 
        I(displayName) attributes). In order to remove an attribute, set its
 
        value to an empty string (C("")), and set the state to
 
        C(replaceattributes).
 
        C(replace).
 
    required: false
 
    default: ""
 
"""
 
@@ -87,19 +88,19 @@ ldap_entry:
 
# Add attribute to an entry.
 
ldap_entry:
 
  dn: uid=john,ou=people,dc=example,dc=com
 
  state: addattributes
 
  state: append
 
  mail: john.doe@example.com
 

	
 
# Make sure the configuration database has specific logging level enabled.
 
ldap_entry:
 
  dn: cn=config
 
  state: replaceattributes
 
  state: replace
 
  olcLogLevel: 256
 

	
 
# Remove attribute from an entry.
 
ldap_entry:
 
  dn: uid=john,ou=people,dc=example,dc=com
 
  state: replaceattributes
 
  state: replace
 
  uid: ""
 
"""
 

	
 
@@ -195,7 +196,7 @@ class LDAPEntry(object):
 

	
 
        return True
 

	
 
    def delete(self):
 
    def remove(self):
 
        """
 
        Removes entry from an LDAP directory.
 

	
 
@@ -212,18 +213,20 @@ class LDAPEntry(object):
 

	
 
        return False
 

	
 
    def addattributes(self):
 
    def append(self):
 
        """
 
        Adds attributes to an existing entry.
 
        Append attributes to an existing entry. If the entry does not exist,
 
        create it.
 

	
 
        Returns:
 

	
 
        True, if entry was updated with new attribute values. False if no change
 
        was necessary (values are already present).
 
        True, if entry was updated with new attribute values or if a new entry
 
        has been created. False if no change was necessary (values are already
 
        present).
 
        """
 

	
 
        if not self.exists():
 
            raise Exception("Module error: Can't add attributes for an entry. Entry does not exist.")
 
            return self.add()
 

	
 
        attribute_list = self.attributes.keys()
 

	
 
@@ -252,18 +255,20 @@ class LDAPEntry(object):
 

	
 
        return True
 

	
 
    def replaceattributes(self):
 
    def replace(self):
 
        """
 
        Replace attributes of an existing entry.
 
        Replace attributes of an existing entry. If the entry does not exist,
 
        create it.
 

	
 
        Returns:
 

	
 
        True, if entry was updated with new attribute values. False if no change
 
        was necessary (values are already present).
 
        True, if entry was updated with new attribute values or if a new entry
 
        has been created. False if no change was necessary (values are already
 
        present).
 
        """
 

	
 
        if not self.exists():
 
            raise Exception("Module error: Can't replace attributes for an entry. Entry does not exist.")
 
            return self.add()
 

	
 
        attribute_list = self.attributes.keys()
 

	
 
@@ -327,7 +332,7 @@ def main():
 
    module = AnsibleModule(
 
        argument_spec=dict(
 
            dn=dict(required=True),
 
            state=dict(required=False, choices=["present", "absent", "addattributes", "replaceattributes"], default="present"),
 
            state=dict(required=False, choices=["present", "absent", "append", "replace"], default="present"),
 
            server_uri=dict(required=False, default="ldapi:///"),
 
            bind_dn=dict(required=False, default=None),
 
            bind_password=dict(required=False)
 
@@ -366,10 +371,10 @@ def main():
 
    try:
 
        if state == "present":
 
            changed = entry.add()
 
        elif state == "addattributes":
 
            changed = entry.addattributes()
 
        elif state == "replaceattributes":
 
            changed = entry.replaceattributes()
 
        elif state == "append":
 
            changed = entry.append()
 
        elif state == "replace":
 
            changed = entry.replace()
 
        else:
 
            changed = entry.remove()
 
    except ldap.LDAPError as e:
roles/ldap_server/tasks/main.yml
Show inline comments
 
@@ -32,7 +32,7 @@
 
  copy: src=slapd_logrotate dest=/etc/logrotate.d/slapd owner=root group=root mode=0644
 

	
 
- name: Change log level for slapd
 
  ldap_entry: dn=cn=config state=replaceattributes olcLogLevel="{{ ldap_server_log_level }}"
 
  ldap_entry: dn=cn=config state=replace olcLogLevel="{{ ldap_server_log_level }}"
 

	
 
- name: Test if LDAP misc schema has been applied
 
  command: ldapsearch -Q -LLL -A -Y EXTERNAL -b cn=schema,cn=config -s one '(cn={*}misc)' cn
 
@@ -56,15 +56,15 @@
 
    - Restart slapd
 

	
 
- name: Configure TLS for slapd
 
  ldap_entry: dn=cn=config state=replaceattributes olcTLSCertificateFile="/etc/ssl/certs/{{ ldap_server_tls_certificate | basename }}" olcTLSCertificateKeyFile="/etc/ssl/private/{{ ldap_server_tls_key | basename }}"
 
  ldap_entry: dn=cn=config state=replace olcTLSCertificateFile="/etc/ssl/certs/{{ ldap_server_tls_certificate | basename }}" olcTLSCertificateKeyFile="/etc/ssl/private/{{ ldap_server_tls_key | basename }}"
 
  notify:
 
    - Restart slapd
 

	
 
- name: Configure SSF
 
  ldap_entry: dn=cn=config state=replaceattributes olcSecurity=ssf="{{ ldap_server_ssf }}" olcLocalSSF="{{ ldap_server_ssf }}"
 
  ldap_entry: dn=cn=config state=replace olcSecurity=ssf="{{ ldap_server_ssf }}" olcLocalSSF="{{ ldap_server_ssf }}"
 

	
 
- name: Enable the memberof module
 
  ldap_entry: dn="cn=module{0},cn=config" state=addattributes olcModuleLoad="{1}memberof"
 
  ldap_entry: dn="cn=module{0},cn=config" state=append olcModuleLoad="{1}memberof"
 

	
 
- name: Enable the memberof overlay for database
 
  ldap_entry:
 
@@ -83,7 +83,58 @@
 
    filter: "(olcSuffix={{ ldap_server_int_basedn }})"
 
    rules: "{{ ldap_permissions }}"
 

	
 
- name: Create LDAP entries
 
- name: Create basic LDAP directory structure
 
  ldap_entry: ""
 
  args:
 
    dn: "ou={{ item }},{{ ldap_server_int_basedn }}"
 
    objectClass:
 
      - organizationalUnit
 
    ou: "{{ item }}"
 
  with_items:
 
    - people
 
    - groups
 
    - services
 

	
 
- name: Create the entry that will contain mail service information
 
  ldap_entry: ""
 
  args:
 
    dn: "ou=mail,ou=services,{{ ldap_server_int_basedn }}"
 
    objectClass: organizationalUnit
 
    ou: mail
 

	
 
- name: Create LDAP directory structure for mail service
 
  ldap_entry: ""
 
  args:
 
    dn: "ou={{ item }},ou=mail,ou=services,{{ ldap_server_int_basedn }}"
 
    objectClass: organizationalUnit
 
    ou: "{{ item }}"
 
  with_items:
 
    - domains
 
    - aliases
 

	
 
- name: Create or remove login entries for services
 
  ldap_entry: ""
 
  args:
 
    dn: "cn={{ item.name }},ou=services,{{ ldap_server_int_basedn }}"
 
    objectClass:
 
      - applicationProcess
 
      - simpleSecurityObject
 
    cn: "{{ item.name }}"
 
    userPassword: "{{ item.password }}"
 
    state: "{{ item.state | default('present') }}"
 
  with_items: ldap_server_consumers
 

	
 
- name: Create or remove user-supplied groups
 
  ldap_entry: ""
 
  args:
 
    dn: "cn={{ item.name }},ou=groups,{{ ldap_server_int_basedn }}"
 
    objectClass: groupOfUniqueNames
 
    cn: "{{ item.name }}"
 
    uniqueMember: "cn=NONE"
 
    state: "{{ item.state | default('append') }}"
 
  with_items: ldap_server_groups
 

	
 
- name: Create user-supplied LDAP entries
 
  ldap_entry: ""
 
  args: "{{ item }}"
 
  with_items: ldap_entries
testsite/group_vars/ldap.yml
Show inline comments
 
@@ -24,7 +24,22 @@ ldap_client_config:
 
    value: demand
 

	
 
ldap_admin_password: admin
 
ldap_server_consumers:
 
  - name: xmpp
 
    password: xmpp
 
  - name: postfix
 
    password: postfix
 
  - name: dovecot
 
    password: dovecot
 
  - name: bollocks
 
    password: "none"
 
    state: absent
 
ldap_server_domain: "{{ testsite_domain }}"
 
ldap_server_groups:
 
  - name: xmpp
 
  - name: mail
 
  - name: blimey
 
    state: absent
 
ldap_server_organization: "Example Inc."
 
ldap_server_log_level: 256
 
ldap_server_tls_certificate: "{{ inventory_dir }}/tls/ldap.{{ testsite_domain }}_ldap.pem"
 
@@ -53,15 +68,6 @@ ldap_permissions:
 
    by * none
 

	
 
ldap_entries:
 
  - dn: ou=people,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: people
 
  - dn: ou=groups,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: groups
 
  - dn: ou=services,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: services
 
  - dn: uid=johndoe,ou=people,{{ testsite_ldap_base }}
 
    objectClass:
 
      - inetOrgPerson
 
@@ -78,48 +84,11 @@ ldap_entries:
 
    sn: Doe
 
    userPassword: janedoe
 
    mail: jane.doe@{{ testsite_domain }}
 
  - dn: cn=xmpp,ou=services,{{ testsite_ldap_base }}
 
    objectClass:
 
      - applicationProcess
 
      - simpleSecurityObject
 
    cn: xmpp
 
    userPassword: xmpp
 
  - dn: cn=xmpp,ou=groups,{{ testsite_ldap_base }}
 
    objectClass: groupOfUniqueNames
 
    cn: xmpp
 
    uniqueMember:
 
      - uid=johndoe,ou=people,{{ testsite_ldap_base }}
 
      - uid=janedoe,ou=people,{{ testsite_ldap_base }}
 
  - dn: cn=postfix,ou=services,{{ testsite_ldap_base }}
 
    objectClass:
 
      - applicationProcess
 
      - simpleSecurityObject
 
    cn: postfix
 
    userPassword: postfix
 
  - dn: cn=dovecot,ou=services,{{ testsite_ldap_base }}
 
    objectClass:
 
      - applicationProcess
 
      - simpleSecurityObject
 
    cn: dovecot
 
    userPassword: dovecot
 
  - dn: cn=mail,ou=groups,{{ testsite_ldap_base }}
 
    objectClass: groupOfUniqueNames
 
    cn: mail
 
  - dn: "cn=mail,ou=groups,{{ testsite_ldap_base }}"
 
    uniqueMember:
 
      - uid=johndoe,ou=people,{{ testsite_ldap_base }}
 
      - uid=janedoe,ou=people,{{ testsite_ldap_base }}
 
  - dn: ou=mail,ou=services,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: mail
 
  - dn: ou=domains,ou=mail,ou=services,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: domains
 
  - dn: ou=aliases,ou=mail,ou=services,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: aliases
 
  - dn: ou=domains,ou=mail,ou=services,{{ testsite_ldap_base }}
 
    objectClass: organizationalUnit
 
    ou: domains
 
    state: append
 
  - dn: dc={{ testsite_domain }},ou=domains,ou=mail,ou=services,{{ testsite_ldap_base }}
 
    objectClass: dNSDomain
 
    dc: "{{ testsite_domain }}"
0 comments (0 inline, 0 general)