From 611ca698669a6516ac4fab04265686897c8abb68 Mon Sep 17 00:00:00 2001 From: George Taylor Date: Thu, 8 Aug 2024 16:21:40 +0100 Subject: [PATCH] :bug: error handling for policy/role recreation --- cli/ldap_cmds/__init__.py | 5 +- cli/ldap_cmds/rbac.py | 117 ++++++++++++++++++++++++++------------ cli/ldap_cmds/user.py | 8 ++- 3 files changed, 90 insertions(+), 40 deletions(-) diff --git a/cli/ldap_cmds/__init__.py b/cli/ldap_cmds/__init__.py index 69110ed..0af0729 100644 --- a/cli/ldap_cmds/__init__.py +++ b/cli/ldap_cmds/__init__.py @@ -7,10 +7,11 @@ # import oracledb def ldap_connect( ldap_host, + ldap_port, ldap_user, - ldap_password, + ldap_password ): - server = Server(ldap_host) + server = Server(ldap_host, ldap_port) return Connection( server=server, diff --git a/cli/ldap_cmds/rbac.py b/cli/ldap_cmds/rbac.py index 4d83ec4..f211ea4 100644 --- a/cli/ldap_cmds/rbac.py +++ b/cli/ldap_cmds/rbac.py @@ -133,7 +133,7 @@ def context_ldif( # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") @@ -171,7 +171,7 @@ def group_ldifs( ): # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") @@ -223,37 +223,61 @@ def policy_ldifs( ): # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") raise e + + log.debug("*********************************") + log.debug("STARTING POLICY LDIFS") + log.debug("*********************************") + policy_files = [file for file in rendered_files if "policy" in Path(file).name] # first, delete the policies ldap_config_dict = env.vars.get("LDAP_CONFIG") or ldap_config policy_tree = "ou=Policies," + ldap_config_dict.get("base_root") - tree = connection.search_s( - policy_tree, - ldap.SCOPE_SUBTREE, - "(objectClass=*)", - ) - tree.reverse() + log.debug(f"Policy tree: {policy_tree}") + + try: + tree = connection.search_s( + policy_tree, + ldap.SCOPE_SUBTREE, + "(objectClass=*)", + ) + tree.reverse() + except ldap.NO_SUCH_OBJECT as no_such_object_e: + log.debug("Entire policy ou does not exist, no need to delete child objects") + tree = None + + log.debug("*********************************") + log.debug("DELETING POLICY ENTRIES") + log.debug("*********************************") + + if tree is not None: + for entry in tree: + try: + log.debug(entry[0]) + connection.delete_ext_s(entry[0], serverctrls=[ldap.controls.simple.ManageDSAITControl()]) + print(f"Deleted {entry[0]}") + except ldap.NO_SUCH_OBJECT as no_such_object_e: + log.debug(f"this is the entry {entry}") + log.debug("error deleting entry") + log.info("No such object found, 32") + log.debug(no_such_object_e) - for entry in tree: - try: - log.debug(entry[0]) - connection.delete_ext_s(entry[0], serverctrls=[ldap.controls.simple.ManageDSAITControl()]) - print(f"Deleted {entry[0]}") - except ldap.NO_SUCH_OBJECT as no_such_object_e: - log.info("No such object found, 32") - log.debug(no_such_object_e) + log.debug("*********************************") + log.debug("RECREATING POLICY ENTRIES") + log.debug("*********************************") # loop through the policy files for file in policy_files: # parse the ldif into dn and record + # + log.debug(f"Reading file {file}") records = ldif.LDIFRecordList(open(file, "rb")) records.parse() @@ -277,6 +301,9 @@ def policy_ldifs( except Exception as e: log.exception(f"Failed to add {dn}... {attributes}") raise e + log.debug("*********************************") + log.debug("FINISHED POLICY LDIFS") + log.debug("*********************************") def role_ldifs( @@ -284,12 +311,16 @@ def role_ldifs( ): # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") raise e + log.debug("*********************************") + log.debug("STARTING ROLES") + log.debug("*********************************") + role_files = [file for file in rendered_files if "nd_role" in Path(file).name] # first, delete the roles @@ -299,26 +330,36 @@ def role_ldifs( "cn=ndRoleCatalogue," + ldap_config_dict.get("base_users"), "cn=ndRoleGroups," + ldap_config_dict.get("base_users"), ] - for role_tree in role_trees: - tree = connection.search_s( - role_tree, - ldap.SCOPE_SUBTREE, - "(objectClass=*)", - ) - tree.reverse() - for entry in tree: - try: - log.debug(entry[0]) - connection.delete_ext_s(entry[0], serverctrls=[ldap.controls.simple.ManageDSAITControl()]) - print(f"Deleted {entry[0]}") - except ldap.NO_SUCH_OBJECT as no_such_object_e: - log.info("No such object found, 32") - log.debug(no_such_object_e) + for role_tree in role_trees: + try: + tree = connection.search_s( + role_tree, + ldap.SCOPE_SUBTREE, + "(objectClass=*)", + ) + tree.reverse() + except ldap.NO_SUCH_OBJECT as no_such_object_e: + log.debug("Entire role ou does not exist, no need to delete child objects") + tree = None + log.debug("*********************************") + log.debug("DELETING ROLES") + log.debug("*********************************") + if tree is not None: + for entry in tree: + try: + log.debug(entry[0]) + connection.delete_ext_s(entry[0], serverctrls=[ldap.controls.simple.ManageDSAITControl()]) + print(f"Deleted {entry[0]}") + except ldap.NO_SUCH_OBJECT as no_such_object_e: + log.info("No such object found, 32") + log.debug(no_such_object_e) # ensure boolean values are Uppercase.. this comes from the ansible yml # (not yet implemented, probably not needed) - + log.debug("*********************************") + log.debug("RECREATING ROLES") + log.debug("*********************************") # loop through the role files for file in role_files: # parse the ldif into dn and record @@ -345,7 +386,9 @@ def role_ldifs( except Exception as e: log.exception(f"Failed to add {dn}... {attributes}") raise e - + log.debug("*********************************") + log.debug("FINISHED ROLES") + log.debug("*********************************") # not complete!! # see https://github.com/ministryofjustice/hmpps-delius-pipelines/blob/master/components/delius-core/playbooks/rbac/import_schemas.yml @@ -354,7 +397,7 @@ def schema_ldifs( ): # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") @@ -390,7 +433,7 @@ def user_ldifs( ): # connect to ldap try: - connection = ldap.initialize("ldap://" + env.vars.get("LDAP_HOST")) + connection = ldap.initialize(f"ldap://{env.vars.get("LDAP_HOST")}:{env.vars.get('LDAP_PORT')}") connection.simple_bind_s(env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD")) except Exception as e: log.exception(f"Failed to connect to ldap") diff --git a/cli/ldap_cmds/user.py b/cli/ldap_cmds/user.py index 2ad4a02..f59de08 100644 --- a/cli/ldap_cmds/user.py +++ b/cli/ldap_cmds/user.py @@ -46,6 +46,7 @@ def change_home_areas( log.info(f"Updating user home areas from {old_home_area} to {new_home_area}") ldap_connection = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), ) @@ -106,7 +107,7 @@ def parse_user_role_list( def add_roles_to_user(username, roles, user_ou="ou=Users", root_dn="dc=moj,dc=com"): log.info(f"Adding roles {roles} to user {username}") ldap_connection = ldap_connect( - env.vars.get("LDAP_HOST"), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD") + env.vars.get("LDAP_HOST"), env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD") ) for role in roles: try: @@ -280,6 +281,7 @@ def update_roles(roles, user_ou, root_dn, add, remove, update_notes, user_note, try: ldap_connection_action = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), ) @@ -405,6 +407,7 @@ def deactivate_crc_users(user_ou, root_dn): log.info("Deactivating CRC users") ldap_connection = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), ) @@ -502,6 +505,7 @@ def user_expiry(user_ou, root_dn): ldap_connection_lock = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), ) @@ -540,6 +544,7 @@ def user_expiry(user_ou, root_dn): ldap_connection_unlock = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), ) @@ -578,6 +583,7 @@ def remove_all_user_passwords(user_ou, root_dn): ldap_connection = ldap_connect( env.vars.get("LDAP_HOST"), + env.vars.get("LDAP_PORT", 389), env.vars.get("LDAP_USER"), env.secrets.get("LDAP_BIND_PASSWORD"), )