openshift adm group sync/prune (#125)

This commit is contained in:
abikouo
2022-01-20 17:23:30 +01:00
committed by GitHub
parent eb11821b3c
commit 0a1a647e37
23 changed files with 3150 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
name:
- kubernetes>=12.0.0
- coverage
- python-ldap
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no

View File

@@ -0,0 +1,4 @@
---
ldap_admin_user: "admin"
ldap_admin_password: "testing123!"
ldap_root: "dc=ansible,dc=redhat"

View File

@@ -0,0 +1,186 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
module: openshift_ldap_entry
short_description: add/remove entry to LDAP Server.
author:
- Aubin Bikouo (@abikouo)
description:
- This module perform basic operations on the LDAP Server (add/remove entries).
- Similar to `community.general.ldap_entry` this has been created to avoid dependency with this collection for the test.
- This module is not supported outside of testing this collection.
options:
attributes:
description:
- If I(state=present), attributes necessary to create an entry. Existing
entries are never modified. To assert specific attribute values on an
existing entry, use M(community.general.ldap_attrs) module instead.
type: dict
objectClass:
description:
- If I(state=present), value or list of values to use when creating
the entry. It can either be a string or an actual list of
strings.
type: list
elements: str
state:
description:
- The target state of the entry.
choices: [present, absent]
default: present
type: str
bind_dn:
description:
- A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism as default.
- If this is blank, we'll use an anonymous bind.
type: str
required: true
bind_pw:
description:
- The password to use with I(bind_dn).
type: str
dn:
required: true
description:
- The DN of the entry to add or remove.
type: str
server_uri:
description:
- A URI to the LDAP server.
- The default value lets the underlying LDAP client library look for a UNIX domain socket in its default location.
type: str
default: ldapi:///
requirements:
- python-ldap
'''
EXAMPLES = r'''
'''
RETURN = r'''
# Default return values
'''
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native, to_bytes
LDAP_IMP_ERR = None
try:
import ldap
import ldap.modlist
HAS_LDAP = True
except ImportError:
LDAP_IMP_ERR = traceback.format_exc()
HAS_LDAP = False
def argument_spec():
args = {}
args['attributes'] = dict(default={}, type='dict')
args['objectClass'] = dict(type='list', elements='str')
args['state'] = dict(default='present', choices=['present', 'absent'])
args['bind_dn'] = dict(required=True)
args['bind_pw'] = dict(default='', no_log=True)
args['dn'] = dict(required=True)
args['server_uri'] = dict(default='ldapi:///')
return args
class LdapEntry(AnsibleModule):
def __init__(self):
AnsibleModule.__init__(
self,
argument_spec=argument_spec(),
required_if=[('state', 'present', ['objectClass'])],
)
if not HAS_LDAP:
self.fail_json(msg=missing_required_lib('python-ldap'), exception=LDAP_IMP_ERR)
self.__connection = None
# Add the objectClass into the list of attributes
self.params['attributes']['objectClass'] = (self.params['objectClass'])
# Load attributes
if self.params['state'] == 'present':
self.attrs = {}
for name, value in self.params['attributes'].items():
if isinstance(value, list):
self.attrs[name] = list(map(to_bytes, value))
else:
self.attrs[name] = [to_bytes(value)]
@property
def connection(self):
if not self.__connection:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
self.__connection = ldap.initialize(self.params['server_uri'])
try:
self.__connection.simple_bind_s(self.params['bind_dn'], self.params['bind_pw'])
except ldap.LDAPError as e:
self.fail_json(msg="Cannot bind to the server due to: %s" % e)
return self.__connection
def add(self):
""" If self.dn does not exist, returns a callable that will add it. """
changed = False
msg = "LDAP Entry '%s' already exist." % self.params["dn"]
if not self._is_entry_present():
modlist = ldap.modlist.addModlist(self.attrs)
self.connection.add_s(self.params['dn'], modlist)
changed = True
msg = "LDAP Entry '%s' successfully created." % self.params["dn"]
self.exit_json(changed=changed, msg=msg)
def delete(self):
""" If self.dn exists, returns a callable that will delete it. """
changed = False
msg = "LDAP Entry '%s' does not exist." % self.params["dn"]
if self._is_entry_present():
self.connection.delete_s(self.params['dn'])
changed = True
msg = "LDAP Entry '%s' successfully deleted." % self.params["dn"]
self.exit_json(changed=changed, msg=msg)
def _is_entry_present(self):
try:
self.connection.search_s(self.params['dn'], ldap.SCOPE_BASE)
except ldap.NO_SUCH_OBJECT:
is_present = False
else:
is_present = True
return is_present
def execute(self):
try:
if self.params['state'] == 'present':
self.add()
else:
self.delete()
except Exception as e:
self.fail_json(msg="Entry action failed.", details=to_native(e), exception=traceback.format_exc())
def main():
module = LdapEntry()
module.execute()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,109 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
module: openshift_ldap_entry_info
short_description: Validate entry from LDAP server.
author:
- Aubin Bikouo (@abikouo)
description:
- This module connect to a ldap server and search for entry.
- This module is not supported outside of testing this collection.
options:
bind_dn:
description:
- A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism as default.
- If this is blank, we'll use an anonymous bind.
type: str
required: true
bind_pw:
description:
- The password to use with I(bind_dn).
type: str
required: True
dn:
description:
- The DN of the entry to test.
type: str
required: True
server_uri:
description:
- A URI to the LDAP server.
- The default value lets the underlying LDAP client library look for a UNIX domain socket in its default location.
type: str
default: ldapi:///
required: True
requirements:
- python-ldap
'''
EXAMPLES = r'''
'''
RETURN = r'''
# Default return values
'''
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
LDAP_IMP_ERR = None
try:
import ldap
import ldap.modlist
HAS_LDAP = True
except ImportError:
LDAP_IMP_ERR = traceback.format_exc()
HAS_LDAP = False
def argument_spec():
args = {}
args['bind_dn'] = dict(required=True)
args['bind_pw'] = dict(required=True, no_log=True)
args['dn'] = dict(required=True)
args['server_uri'] = dict(required=True)
return args
def execute():
module = AnsibleModule(
argument_spec=argument_spec(),
supports_check_mode=True
)
if not HAS_LDAP:
module.fail_json(msg=missing_required_lib("python-ldap"), exception=LDAP_IMP_ERR)
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
connection = ldap.initialize(module.params['server_uri'])
try:
connection.simple_bind_s(module.params['bind_dn'], module.params['bind_pw'])
except ldap.LDAPError as e:
module.fail_json(msg="Cannot bind to the server due to: %s" % e)
try:
connection.search_s(module.params['dn'], ldap.SCOPE_BASE)
module.exit_json(changed=False, found=True)
except ldap.NO_SUCH_OBJECT:
module.exit_json(changed=False, found=False)
def main():
execute()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,4 @@
---
collections:
- community.okd
- kubernetes.core

View File

@@ -0,0 +1,235 @@
- block:
- name: Get LDAP definition
set_fact:
ldap_entries: "{{ lookup('template', 'ad/definition.j2') | from_yaml }}"
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- admins
- developers
- name: Delete existing LDAP Entries
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
state: absent
with_items: "{{ ldap_entries.users + ldap_entries.units | reverse | list }}"
- name: Create LDAP Entries
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
attributes: "{{ item.attr }}"
objectClass: "{{ item.class }}"
with_items: "{{ ldap_entries.units + ldap_entries.users }}"
- name: Load test configurations
set_fact:
sync_config: "{{ lookup('template', 'ad/sync-config.j2') | from_yaml }}"
- name: Synchronize Groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
check_mode: yes
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- admins_group
- devs_group
- '"jane.smith@ansible.org" in {{ admins_group.users }}'
- '"jim.adams@ansible.org" in {{ admins_group.users }}'
- '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- admins_group.users | length == 2
- devs_group.users | length == 1
vars:
admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
- name: Synchronize Groups (Remove check_mode)
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- name: Read admins group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: Validate group was created
assert:
that:
- result.resources | length == 1
- '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
- '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
- name: Read developers group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: Validate group was created
assert:
that:
- result.resources | length == 1
- '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
- name: Define user dn to delete
set_fact:
user_to_delete: "cn=Jane,ou=engineers,ou=activeD,{{ ldap_root }}"
- name: Delete 1 admin user
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ user_to_delete }}"
state: absent
- name: Synchronize Openshift groups using allow_groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
allow_groups:
- developers
type: openshift
register: openshift_sync
- name: Validate that only developers group was sync
assert:
that:
- openshift_sync is changed
- openshift_sync.groups | length == 1
- openshift_sync.groups.0.metadata.name == "developers"
- name: Read admins group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: Validate admins group content has not changed
assert:
that:
- result.resources | length == 1
- '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
- '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
- name: Synchronize Openshift groups using deny_groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
deny_groups:
- developers
type: openshift
register: openshift_sync
- name: Validate that only admins group was sync
assert:
that:
- openshift_sync is changed
- openshift_sync.groups | length == 1
- openshift_sync.groups.0.metadata.name == "admins"
- name: Read admins group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: Validate admins group contains only 1 user now
assert:
that:
- result.resources | length == 1
- result.resources.0.users == ["jim.adams@ansible.org"]
- name: Set users to delete (delete all developers users)
set_fact:
user_to_delete: "cn=Jordan,ou=engineers,ou=activeD,{{ ldap_root }}"
- name: Delete 1 admin user
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ user_to_delete }}"
state: absent
- name: Prune groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
state: absent
register: result
- name: Validate result is changed (only developers group be deleted)
assert:
that:
- result is changed
- result.groups | length == 1
- name: Get developers group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: assert group was deleted
assert:
that:
- result.resources | length == 0
- name: Get admins group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: assert group was not deleted
assert:
that:
- result.resources | length == 1
- name: Prune groups once again (idempotency)
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
state: absent
register: result
- name: Assert nothing was changed
assert:
that:
- result is not changed
always:
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- admins
- developers

View File

@@ -0,0 +1,174 @@
- block:
- name: Get LDAP definition
set_fact:
ldap_entries: "{{ lookup('template', 'augmented-ad/definition.j2') | from_yaml }}"
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- banking
- insurance
- name: Delete existing LDAP entries
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
state: absent
with_items: "{{ ldap_entries.users + ldap_entries.groups + ldap_entries.units | reverse | list }}"
- name: Create LDAP Entries
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
attributes: "{{ item.attr }}"
objectClass: "{{ item.class }}"
with_items: "{{ ldap_entries.units + ldap_entries.groups + ldap_entries.users }}"
- name: Load test configurations
set_fact:
sync_config: "{{ lookup('template', 'augmented-ad/sync-config.j2') | from_yaml }}"
- name: Synchronize Groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
check_mode: yes
register: result
- name: Validate that 'banking' and 'insurance' groups were created
assert:
that:
- result is changed
- banking_group
- insurance_group
- '"james-allan@ansible.org" in {{ banking_group.users }}'
- '"gordon-kane@ansible.org" in {{ banking_group.users }}'
- '"alice-courtney@ansible.org" in {{ insurance_group.users }}'
- banking_group.users | length == 2
- insurance_group.users | length == 1
vars:
banking_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'banking') | first }}"
insurance_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'insurance') | first }}"
- name: Synchronize Groups (Remove check_mode)
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- name: Define facts for group to create
set_fact:
ldap_groups:
- name: banking
users:
- "james-allan@ansible.org"
- "gordon-kane@ansible.org"
- name: insurance
users:
- "alice-courtney@ansible.org"
- name: Read 'banking' openshift group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: banking
register: result
- name: Validate group info
assert:
that:
- result.resources | length == 1
- '"james-allan@ansible.org" in {{ result.resources.0.users }}'
- '"gordon-kane@ansible.org" in {{ result.resources.0.users }}'
- name: Read 'insurance' openshift group
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: insurance
register: result
- name: Validate group info
assert:
that:
- result.resources | length == 1
- 'result.resources.0.users == ["alice-courtney@ansible.org"]'
- name: Delete employee from 'insurance' group
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "cn=Alice,ou=employee,ou=augmentedAD,{{ ldap_root }}"
state: absent
- name: Prune groups
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
state: absent
register: result
- name: Validate result is changed (only insurance group be deleted)
assert:
that:
- result is changed
- result.groups | length == 1
- name: Get 'insurance' openshift group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: insurance
register: result
- name: assert group was deleted
assert:
that:
- result.resources | length == 0
- name: Get 'banking' openshift group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: banking
register: result
- name: assert group was not deleted
assert:
that:
- result.resources | length == 1
- name: Prune groups once again (idempotency)
community.okd.openshift_adm_groups_sync:
config: "{{ sync_config }}"
state: absent
register: result
- name: Assert no change was made
assert:
that:
- result is not changed
always:
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- banking
- insurance

View File

@@ -0,0 +1,61 @@
---
- name: Get cluster information
kubernetes.core.k8s_cluster_info:
register: info
- name: Create LDAP Pod
community.okd.k8s:
namespace: "default"
wait: yes
definition:
kind: Pod
apiVersion: v1
metadata:
name: ldap-pod
labels:
app: ldap
spec:
containers:
- name: ldap
image: bitnami/openldap
env:
- name: LDAP_ADMIN_USERNAME
value: "{{ ldap_admin_user }}"
- name: LDAP_ADMIN_PASSWORD
value: "{{ ldap_admin_password }}"
- name: LDAP_USERS
value: "ansible"
- name: LDAP_PASSWORDS
value: "ansible123"
- name: LDAP_ROOT
value: "{{ ldap_root }}"
ports:
- containerPort: 1389
register: pod_info
- name: Set Pod Internal IP
set_fact:
podIp: "{{ pod_info.result.status.podIP }}"
- name: Set LDAP Common facts
set_fact:
ldap_server_uri: "ldap://{{ podIp }}:1389"
ldap_bind_dn: "cn={{ ldap_admin_user }},{{ ldap_root }}"
ldap_bind_pw: "{{ ldap_admin_password }}"
- name: Display LDAP Server URI
debug:
var: ldap_server_uri
- name: Test existing user from LDAP server
openshift_ldap_entry_info:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
dn: "ou=users,{{ ldap_root }}"
server_uri: "{{ ldap_server_uri }}"
# ignore_errors: true
# register: ping_ldap
- include_tasks: "tasks/rfc2307.yml"
- include_tasks: "tasks/activeDirectory.yml"
- include_tasks: "tasks/augmentedActiveDirectory.yml"

View File

@@ -0,0 +1,468 @@
- block:
- name: Get LDAP definition
set_fact:
ldap_resources: "{{ lookup('template', 'rfc2307/definition.j2') | from_yaml }}"
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- admins
- engineers
- developers
- name: Delete existing LDAP entries
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
state: absent
with_items: "{{ ldap_resources.users + ldap_resources.groups + ldap_resources.units | reverse | list }}"
- name: Create LDAP units
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
attributes: "{{ item.attr }}"
objectClass: "{{ item.class }}"
with_items: "{{ ldap_resources.units }}"
- name: Create LDAP Groups
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
attributes: "{{ item.attr }}"
objectClass: "{{ item.class }}"
with_items: "{{ ldap_resources.groups }}"
- name: Create LDAP users
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item.dn }}"
attributes: "{{ item.attr }}"
objectClass: "{{ item.class }}"
with_items: "{{ ldap_resources.users }}"
- name: Load test configurations
set_fact:
configs: "{{ lookup('template', 'rfc2307/sync-config.j2') | from_yaml }}"
- name: Synchronize Groups
community.okd.openshift_adm_groups_sync:
config: "{{ configs.simple }}"
check_mode: yes
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- admins_group
- devs_group
- '"jane.smith@ansible.org" in {{ admins_group.users }}'
- '"jim.adams@ansible.org" in {{ devs_group.users }}'
- '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- admins_group.users | length == 1
- devs_group.users | length == 2
vars:
admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
- name: Synchronize Groups - User defined mapping
community.okd.openshift_adm_groups_sync:
config: "{{ configs.user_defined }}"
check_mode: yes
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- admins_group
- devs_group
- '"jane.smith@ansible.org" in {{ admins_group.users }}'
- '"jim.adams@ansible.org" in {{ devs_group.users }}'
- '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- admins_group.users | length == 1
- devs_group.users | length == 2
vars:
admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-devs') | first }}"
- name: Synchronize Groups - Using dn for every query
community.okd.openshift_adm_groups_sync:
config: "{{ configs.dn_everywhere }}"
check_mode: yes
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- admins_group
- devs_group
- '"cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ admins_group.users }}'
- '"cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
- '"cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
- admins_group.users | length == 1
- devs_group.users | length == 2
vars:
admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=admins,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=developers,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
- name: Synchronize Groups - Partially user defined mapping
community.okd.openshift_adm_groups_sync:
config: "{{ configs.partially_user_defined }}"
check_mode: yes
register: result
- name: Validate Group going to be created
assert:
that:
- result is changed
- admins_group
- devs_group
- '"jane.smith@ansible.org" in {{ admins_group.users }}'
- '"jim.adams@ansible.org" in {{ devs_group.users }}'
- '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- admins_group.users | length == 1
- devs_group.users | length == 2
vars:
admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
- name: Delete Group 'engineers' if created before
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: 'engineers'
wait: yes
ignore_errors: yes
- name: Synchronize Groups - Partially user defined mapping
community.okd.openshift_adm_groups_sync:
config: "{{ configs.out_scope }}"
check_mode: yes
register: result
ignore_errors: yes
- name: Assert group sync failed due to non-existent member
assert:
that:
- result is failed
- result.msg.startswith("Entry not found for base='cn=Matthew,ou=people,ou=outrfc2307,{{ ldap_root }}'")
- name: Define sync configuration with tolerateMemberNotFoundErrors
set_fact:
config_out_of_scope_tolerate_not_found: "{{ configs.out_scope | combine({'rfc2307': merge_rfc2307 })}}"
vars:
merge_rfc2307: "{{ configs.out_scope.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
- name: Synchronize Groups - Partially user defined mapping (tolerateMemberNotFoundErrors=true)
community.okd.openshift_adm_groups_sync:
config: "{{ config_out_of_scope_tolerate_not_found }}"
check_mode: yes
register: result
- name: Assert group sync did not fail (tolerateMemberNotFoundErrors=true)
assert:
that:
- result is changed
- result.groups | length == 1
- result.groups.0.metadata.name == 'engineers'
- result.groups.0.users == ['Abraham']
- name: Create Group 'engineers'
community.okd.k8s:
state: present
wait: yes
definition:
kind: Group
apiVersion: "user.openshift.io/v1"
metadata:
name: engineers
users: []
- name: Try to sync LDAP group with Openshift existing group not created using sync should failed
community.okd.openshift_adm_groups_sync:
config: "{{ config_out_of_scope_tolerate_not_found }}"
check_mode: yes
register: result
ignore_errors: yes
- name: Validate group sync failed
assert:
that:
- result is failed
- '"openshift.io/ldap.host label did not match sync host" in result.msg'
- name: Define allow_groups and deny_groups groups
set_fact:
allow_groups:
- "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
deny_groups:
- "cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}"
- name: Synchronize Groups using allow_groups
community.okd.openshift_adm_groups_sync:
config: "{{ configs.simple }}"
allow_groups: "{{ allow_groups }}"
register: result
check_mode: yes
- name: Validate Group going to be created
assert:
that:
- result is changed
- result.groups | length == 1
- result.groups.0.metadata.name == "developers"
- name: Synchronize Groups using deny_groups
community.okd.openshift_adm_groups_sync:
config: "{{ configs.simple }}"
deny_groups: "{{ deny_groups }}"
register: result
check_mode: yes
- name: Validate Group going to be created
assert:
that:
- result is changed
- result.groups | length == 1
- result.groups.0.metadata.name == "developers"
- name: Synchronize groups, remove check_mode
community.okd.openshift_adm_groups_sync:
config: "{{ configs.simple }}"
register: result
- name: Validate result is changed
assert:
that:
- result is changed
- name: Read Groups
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: Validate group was created
assert:
that:
- result.resources | length == 1
- '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
- name: Read Groups
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: Validate group was created
assert:
that:
- result.resources | length == 1
- '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
- '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
- name: Set users to delete (no admins users anymore and only 1 developer kept)
set_fact:
users_to_delete:
- "cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}"
- "cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}"
- name: Delete users from LDAP servers
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item }}"
state: absent
with_items: "{{ users_to_delete }}"
- name: Define sync configuration with tolerateMemberNotFoundErrors
set_fact:
config_simple_tolerate_not_found: "{{ configs.simple | combine({'rfc2307': merge_rfc2307 })}}"
vars:
merge_rfc2307: "{{ configs.simple.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
- name: Synchronize groups once again after users deletion
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
register: result
- name: Validate result is changed
assert:
that:
- result is changed
- name: Read Groups
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: Validate admins group does not contains users anymore
assert:
that:
- result.resources | length == 1
- result.resources.0.users == []
- name: Read Groups
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: Validate group was created
assert:
that:
- result.resources | length == 1
- '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
- name: Set group to delete
set_fact:
groups_to_delete:
- "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
- name: Delete Group from LDAP servers
openshift_ldap_entry:
bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}"
server_uri: "{{ ldap_server_uri }}"
dn: "{{ item }}"
state: absent
with_items: "{{ groups_to_delete }}"
- name: Prune groups
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
state: absent
register: result
check_mode: yes
- name: Validate that only developers group is candidate for Prune
assert:
that:
- result is changed
- result.groups | length == 1
- result.groups.0.metadata.name == "developers"
- name: Read Group (validate that check_mode did not performed update in the cluster)
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: Assert group was found
assert:
that:
- result.resources | length == 1
- name: Prune using allow_groups
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
allow_groups:
- developers
state: absent
register: result
check_mode: yes
- name: assert developers group was candidate for prune
assert:
that:
- result is changed
- result.groups | length == 1
- result.groups.0.metadata.name == "developers"
- name: Prune using deny_groups
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
deny_groups:
- developers
state: absent
register: result
check_mode: yes
- name: assert nothing found candidate for prune
assert:
that:
- result is not changed
- result.groups | length == 0
- name: Prune groups
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
state: absent
register: result
- name: Validate result is changed
assert:
that:
- result is changed
- result.groups | length == 1
- name: Get developers group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: developers
register: result
- name: assert group was deleted
assert:
that:
- result.resources | length == 0
- name: Get admins group info
kubernetes.core.k8s_info:
kind: Group
version: "user.openshift.io/v1"
name: admins
register: result
- name: assert group was not deleted
assert:
that:
- result.resources | length == 1
- name: Prune groups once again (idempotency)
community.okd.openshift_adm_groups_sync:
config: "{{ config_simple_tolerate_not_found }}"
state: absent
register: result
- name: Assert nothing changed
assert:
that:
- result is not changed
- result.groups | length == 0
always:
- name: Delete openshift groups if existing
community.okd.k8s:
state: absent
kind: Group
version: "user.openshift.io/v1"
name: "{{ item }}"
with_items:
- admins
- engineers
- developers

View File

@@ -0,0 +1,39 @@
units:
- dn: "ou=activeD,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: activeD
- dn: "ou=engineers,ou=activeD,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: engineers
users:
- dn: cn=Jane,ou=engineers,ou=activeD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: Jane
sn: Smith
displayName: Jane Smith
mail: jane.smith@ansible.org
employeeType: admins
- dn: cn=Jim,ou=engineers,ou=activeD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: Jim
sn: Adams
displayName: Jim Adams
mail: jim.adams@ansible.org
employeeType: admins
- dn: cn=Jordan,ou=engineers,ou=activeD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: Jordan
sn: Bulls
displayName: Jordan Bulls
mail: jordanbulls@ansible.org
employeeType: developers

View File

@@ -0,0 +1,12 @@
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
activeDirectory:
usersQuery:
baseDN: "ou=engineers,ou=activeD,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=inetOrgPerson)
userNameAttributes: [ mail ]
groupMembershipAttributes: [ employeeType ]

View File

@@ -0,0 +1,59 @@
units:
- dn: "ou=augmentedAD,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: augmentedAD
- dn: "ou=employee,ou=augmentedAD,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: employee
- dn: "ou=category,ou=augmentedAD,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: category
groups:
- dn: "cn=banking,ou=category,ou=augmentedAD,{{ ldap_root }}"
class:
- groupOfNames
attr:
cn: banking
description: Banking employees
member:
- cn=James,ou=employee,ou=augmentedAD,{{ ldap_root }}
- cn=Gordon,ou=employee,ou=augmentedAD,{{ ldap_root }}
- dn: "cn=insurance,ou=category,ou=augmentedAD,{{ ldap_root }}"
class:
- groupOfNames
attr:
cn: insurance
description: Insurance employees
member:
- cn=Alice,ou=employee,ou=augmentedAD,{{ ldap_root }}
users:
- dn: cn=James,ou=employee,ou=augmentedAD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: James
sn: Allan
mail: james-allan@ansible.org
businessCategory: cn=banking,ou=category,ou=augmentedAD,{{ ldap_root }}
- dn: cn=Gordon,ou=employee,ou=augmentedAD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: Gordon
sn: Kane
mail: gordon-kane@ansible.org
businessCategory: cn=banking,ou=category,ou=augmentedAD,{{ ldap_root }}
- dn: cn=Alice,ou=employee,ou=augmentedAD,{{ ldap_root }}
class:
- inetOrgPerson
attr:
cn: Alice
sn: Courtney
mail: alice-courtney@ansible.org
businessCategory: cn=insurance,ou=category,ou=augmentedAD,{{ ldap_root }}

View File

@@ -0,0 +1,20 @@
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
augmentedActiveDirectory:
groupsQuery:
baseDN: "ou=category,ou=augmentedAD,{{ ldap_root }}"
scope: sub
derefAliases: never
pageSize: 0
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
usersQuery:
baseDN: "ou=employee,ou=augmentedAD,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=inetOrgPerson)
pageSize: 0
userNameAttributes: [ mail ]
groupMembershipAttributes: [ businessCategory ]

View File

@@ -0,0 +1,102 @@
units:
- dn: "ou=rfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: rfc2307
- dn: "ou=groups,ou=rfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: groups
- dn: "ou=people,ou=rfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: people
- dn: "ou=outrfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: outrfc2307
- dn: "ou=groups,ou=outrfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: groups
- dn: "ou=people,ou=outrfc2307,{{ ldap_root }}"
class:
- organizationalUnit
attr:
ou: people
groups:
- dn: "cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}"
class:
- groupOfNames
attr:
cn: admins
description: System Administrators
member:
- cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}
- dn: "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
class:
- groupOfNames
attr:
cn: developers
description: Developers
member:
- cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}
- cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}
- dn: "cn=engineers,ou=groups,ou=outrfc2307,{{ ldap_root }}"
class:
- groupOfNames
attr:
cn: engineers
description: Engineers
member:
- cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}
- cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}
- cn=Julia,ou=people,ou=outrfc2307,{{ ldap_root }}
- cn=Matthew,ou=people,ou=outrfc2307,{{ ldap_root }}
users:
- dn: cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}
class:
- person
- organizationalPerson
- inetOrgPerson
attr:
cn: Jane
sn: Smith
displayName: Jane Smith
mail: jane.smith@ansible.org
admin: yes
- dn: cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}
class:
- person
- organizationalPerson
- inetOrgPerson
attr:
cn: Jim
sn: Adams
displayName: Jim Adams
mail: jim.adams@ansible.org
- dn: cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}
class:
- person
- organizationalPerson
- inetOrgPerson
attr:
cn: Jordan
sn: Bulls
displayName: Jordan Bulls
mail: jordanbulls@ansible.org
- dn: cn=Julia,ou=people,ou=outrfc2307,{{ ldap_root }}
class:
- person
- organizationalPerson
- inetOrgPerson
attr:
cn: Julia
sn: Abraham
displayName: Julia Abraham
mail: juliaabraham@ansible.org

View File

@@ -0,0 +1,105 @@
simple:
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
rfc2307:
groupsQuery:
baseDN: "ou=groups,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=groupOfNames)
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=people,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ mail ]
user_defined:
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
groupUIDNameMapping:
"cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}": ansible-admins
"cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}": ansible-devs
rfc2307:
groupsQuery:
baseDN: "ou=groups,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=groupOfNames)
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=people,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ mail ]
partially_user_defined:
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
groupUIDNameMapping:
"cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}": ansible-admins
rfc2307:
groupsQuery:
baseDN: "ou=groups,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=groupOfNames)
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=people,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ mail ]
dn_everywhere:
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
rfc2307:
groupsQuery:
baseDN: "ou=groups,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=groupOfNames)
groupUIDAttribute: dn
groupNameAttributes: [ dn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=people,ou=rfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ dn ]
out_scope:
kind: LDAPSyncConfig
apiVersion: v1
url: "{{ ldap_server_uri }}"
insecure: true
rfc2307:
groupsQuery:
baseDN: "ou=groups,ou=outrfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
filter: (objectclass=groupOfNames)
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=people,ou=outrfc2307,{{ ldap_root }}"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ sn ]

View File

@@ -81,3 +81,6 @@
kind: Namespace
name: process-test
state: absent
roles:
- role: openshift_adm_groups