From d33df5c23d46f1d172f5338e9897154e5b0e9f32 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Sun, 1 May 2022 02:39:51 +0200 Subject: [PATCH] Fix pylint/flake8 warnings --- check_syncrepl_extended | 213 +++++++++++++++++++++++++--------------- setup.cfg | 2 + 2 files changed, 134 insertions(+), 81 deletions(-) create mode 100644 setup.cfg diff --git a/check_syncrepl_extended b/check_syncrepl_extended index e92069f..c9ef07a 100755 --- a/check_syncrepl_extended +++ b/check_syncrepl_extended @@ -43,15 +43,17 @@ import getpass import ldap from ldap import LDAPError # pylint: disable=no-name-in-module from ldap.controls import SimplePagedResultsControl -import ldap.modlist as modlist +from ldap import modlist TOUCH_VALUE = '%%TOUCH%%' parser = argparse.ArgumentParser( - description=("Script to check LDAP syncrepl replication state between "+ - "two servers."), - epilog=("Author: Benjamin Renard , "+ - "Source: https://gogs.zionetrix.net/bn8/check_syncrepl_extended") + description=( + "Script to check LDAP syncrepl replication state between " + "two servers."), + epilog=( + "Author: Benjamin Renard , " + "Source: https://gogs.zionetrix.net/bn8/check_syncrepl_extended") ) parser.add_argument( @@ -75,11 +77,12 @@ parser.add_argument( dest="serverid", action="store", type=int, - help=("Compare contextCSN of a specific master. Useful in MultiMaster "+ - "setups where each master has a unique ID and a contextCSN for "+ - "each replicated master exists. A valid serverID is a integer "+ - "value from 0 to 4095 (limited to 3 hex digits, example: '12' "+ - "compares the contextCSN matching '#00C#')"), + help=( + "Compare contextCSN of a specific master. Useful in MultiMaster " + "setups where each master has a unique ID and a contextCSN for " + "each replicated master exists. A valid serverID is a integer " + "value from 0 to 4095 (limited to 3 hex digits, example: '12' " + "compares the contextCSN matching '#00C#')"), default=False ) @@ -169,8 +172,9 @@ parser.add_argument( "--only-check-contextCSN", dest="onlycheckcontextcsn", action="store_true", - help=("Only check servers root contextCSN (objects check disabled, "+ - "default : False)"), + help=( + "Only check servers root contextCSN (objects check disabled, " + "default : False)"), default=False ) @@ -196,11 +200,13 @@ parser.add_argument( dest="touch", action="store", type=str, - help=("Touch attribute giving in parameter to force resync a this LDAP "+ - "object from provider. A value '{}' will be add to this attribute "+ - "and remove after. The user use to connect to the LDAP directory "+ - "must have write permission on this attribute on each object." - ).format(TOUCH_VALUE), + help=( + 'Touch attribute giving in parameter to force resync a this LDAP ' + f'object from provider. A value "{TOUCH_VALUE}" will be add to this ' + 'attribute and remove after. The user use to connect to the LDAP ' + 'directory must have write permission on this attribute on each ' + 'object.' + ), default=None ) @@ -225,16 +231,18 @@ parser.add_argument( dest="page_size", action="store", type=int, - help=("Page size: if defined, paging control using LDAP v3 extended " + - "control will be enabled."), + help=( + "Page size: if defined, paging control using LDAP v3 extended " + "control will be enabled."), default=None ) options = parser.parse_args() if options.nocheckcontextcsn and options.onlycheckcontextcsn: - parser.error("You can't use both --no-check-contextCSN and "+ - "--only-check-contextCSN parameters and the same time") + parser.error( + "You can't use both --no-check-contextCSN and " + "--only-check-contextCSN parameters and the same time") if options.nagios: sys.exit(3) sys.exit(1) @@ -251,9 +259,11 @@ if not options.basedn: sys.exit(3) sys.exit(1) + if not 0 <= options.serverid <= 4095: - parser.error("ServerID should be a integer value from 0 to 4095 "+ - "(limited to 3 hexadecimal digits).") + parser.error( + "ServerID should be a integer value from 0 to 4095 " + "(limited to 3 hexadecimal digits).") if options.nagios: sys.exit(3) sys.exit(1) @@ -282,7 +292,8 @@ elif options.quiet: else: logging.basicConfig(level=logging.INFO, format=FORMAT) -class LdapServer(object): + +class LdapServer: uri = "" dn = "" @@ -302,7 +313,8 @@ class LdapServer(object): if self.con == 0: try: con = ldap.initialize(self.uri) - con.protocol_version = ldap.VERSION3 # pylint: disable=no-member + # pylint: disable=no-member + con.protocol_version = ldap.VERSION3 if self.start_tls: con.start_tls_s() if self.dn: @@ -316,18 +328,20 @@ class LdapServer(object): def getContextCSN(self, basedn=False, serverid=False): if not basedn: basedn = self.dn - data = self.search(basedn, '(objectclass=*)', attrs=['contextCSN'], scope='base') + data = self.search( + basedn, '(objectclass=*)', attrs=['contextCSN'], scope='base') if data: contextCSNs = data[0][0][1]['contextCSN'] logging.debug('Found contextCSNs %s', contextCSNs) if serverid is False: return contextCSNs[0] csnid = str(format(serverid, 'X')).zfill(3) - sub = str.encode('#%s#' % csnid, encoding="ascii", errors="replace") + sub = str.encode(f'#{csnid}#', encoding="ascii", errors="replace") CSN = [s for s in contextCSNs if sub in s] if not CSN: logging.error( - "No contextCSN matching with ServerID %s (=%s) could be found.", + "No contextCSN matching with ServerID %s (=%s) could be " + "found.", serverid, sub ) return False @@ -342,11 +356,12 @@ class LdapServer(object): return ldap.SCOPE_ONELEVEL # pylint: disable=no-member if scope == 'sub': return ldap.SCOPE_SUBTREE # pylint: disable=no-member - raise Exception("Unknown LDAP scope '%s'" % scope) + raise Exception(f'Unknown LDAP scope "{scope}"') def search(self, basedn, filterstr, attrs=None, scope=None): if self.page_size: - return self.paged_search(basedn, filterstr, attrs=attrs, scope=scope) + return self.paged_search( + basedn, filterstr, attrs=attrs, scope=scope) res_id = self.con.search( basedn, self.get_scope(scope if scope else 'sub'), filterstr, attrs if attrs else [] @@ -371,7 +386,8 @@ class LdapServer(object): basedn, self.get_scope(scope if scope else 'sub'), filterstr, attrs if attrs else [], serverctrls=[pg_ctrl] ) - res_type, res_data, res_id, serverctrls = self.con.result3(res_id) # pylint: disable=unused-variable + # pylint: disable=unused-variable + res_type, res_data, res_id, serverctrls = self.con.result3(res_id) for serverctrl in serverctrls: if serverctrl.controlType == SimplePagedResultsControl.controlType: pg_ctrl.cookie = serverctrl.cookie @@ -382,7 +398,7 @@ class LdapServer(object): def update_object(self, dn, old, new): ldif = modlist.modifyModlist(old, new) - if ldif == []: + if not ldif: return True try: logging.debug('Update object %s: %s', dn, ldif) @@ -419,7 +435,9 @@ class LdapServer(object): dn, attr, old, new ) if self.update_object(dn, old, new): - logging.info('Restore original value of attribute "%s" of object "%s"', attr, dn) + logging.info( + 'Restore original value of attribute "%s" of object "%s"', + attr, dn) if options.removetouchvalue and TOUCH_VALUE in old[attr]: old[attr].remove(TOUCH_VALUE) self.update_object(dn=dn, old=new, new=old) @@ -428,8 +446,11 @@ class LdapServer(object): logging.error('Error touching object "%s"', dn, exc_info=True) return False + if options.nocheckcert: - ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # pylint: disable=no-member + # pylint: disable=no-member + ldap.set_option( + ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) servers = [options.provider, options.consumer] @@ -445,13 +466,14 @@ for srv in servers: if not LdapServers[srv].connect(): if options.nagios: - print("UNKWNON - Failed to connect to %s" % srv) # pylint: disable=print-statement + print(f'UNKWNON - Failed to connect to {srv}') sys.exit(3) else: sys.exit(1) if not options.nocheckcontextcsn: - LdapServersCSN[srv] = LdapServers[srv].getContextCSN(options.basedn, options.serverid) + LdapServersCSN[srv] = LdapServers[srv].getContextCSN( + options.basedn, options.serverid) logging.info('ContextCSN of %s: %s', srv, LdapServersCSN[srv]) if not options.onlycheckcontextcsn: @@ -459,11 +481,15 @@ for srv in servers: LdapObjects[srv] = {} if options.attrs: - for obj in LdapServers[srv].search(options.basedn, options.filterstr, []): + for obj in LdapServers[srv].search( + options.basedn, options.filterstr, [] + ): logging.debug('Found on %s: %s', srv, obj[0][0]) LdapObjects[srv][obj[0][0]] = obj[0][1] else: - for obj in LdapServers[srv].search(options.basedn, options.filterstr, ['entryCSN']): + for obj in LdapServers[srv].search( + options.basedn, options.filterstr, ['entryCSN'] + ): logging.debug( 'Found on %s: %s / %s', srv, obj[0][0], obj[0][1]['entryCSN'][0] @@ -482,33 +508,36 @@ if not options.onlycheckcontextcsn: not_sync[srv] = [] if options.attrs: - logging.info("Check if objects a are synchronized (by comparing attributes's values)") + logging.info( + "Check if objects a are synchronized (by comparing attributes's " + "values)") else: - logging.info('Check if objets are synchronized (by comparing entryCSN)') + logging.info( + 'Check if objets are synchronized (by comparing entryCSN)') for obj in LdapObjects[options.provider]: logging.debug('Check obj %s', obj) - for srv in LdapObjects: - if srv == options.provider: + for srv_name, srv in LdapObjects.items(): + if srv_name == options.provider: continue - if obj in LdapObjects[srv]: + if obj in srv: touch = False - if LdapObjects[options.provider][obj] != LdapObjects[srv][obj]: + if LdapObjects[options.provider][obj] != srv[obj]: if options.attrs: attrs_list = [] for attr in LdapObjects[options.provider][obj]: if attr in excl_attrs: continue - if attr not in LdapObjects[srv][obj]: + if attr not in srv[obj]: attrs_list.append(attr) logging.debug( "Obj %s not synchronized: %s not present on %s", - obj, ','.join(attrs_list), srv + obj, ','.join(attrs_list), srv_name ) touch = True else: - LdapObjects[srv][obj][attr].sort() + srv[obj][attr].sort() LdapObjects[options.provider][obj][attr].sort() - if LdapObjects[srv][obj][attr] != LdapObjects[options.provider][obj][attr]: + if srv[obj][attr] != LdapObjects[options.provider][obj][attr]: attrs_list.append(attr) logging.debug( "Obj %s not synchronized: %s not same value(s)", @@ -516,26 +545,28 @@ if not options.onlycheckcontextcsn: ) touch = True if attrs_list: - not_sync[srv].append("%s (%s)" % (obj, ','.join(attrs_list))) + not_sync[srv_name].append(f'{obj} ({",".join(attrs_list)})') else: logging.debug( "Obj %s not synchronized: %s <-> %s", - obj, LdapObjects[options.provider][obj], LdapObjects[srv][obj] + obj, LdapObjects[options.provider][obj], srv[obj] ) - not_sync[srv].append(obj) + not_sync[srv_name].append(obj) if touch and options.touch: orig_value = [] if options.touch in LdapObjects[options.provider][obj]: orig_value = LdapObjects[options.provider][obj][options.touch] - LdapServers[options.provider].touch_object(obj, options.touch, orig_value) + LdapServers[options.provider].touch_object( + obj, options.touch, orig_value) else: - logging.debug('Obj %s: not found on %s', obj, srv) - not_found[srv].append(obj) + logging.debug('Obj %s: not found on %s', obj, srv_name) + not_found[srv_name].append(obj) if options.touch: orig_value = [] if options.touch in LdapObjects[options.provider][obj]: orig_value = LdapObjects[options.provider][obj][options.touch] - LdapServers[options.provider].touch_object(obj, options.touch, orig_value) + LdapServers[options.provider].touch_object( + obj, options.touch, orig_value) for obj in LdapObjects[options.consumer]: logging.debug('Check obj %s of consumer', obj) @@ -551,54 +582,74 @@ if options.nagios: if not LdapServersCSN[options.provider]: errors.append('ContextCSN of LDAP server provider could not be found') else: - long_output.append('ContextCSN on LDAP server provider = %s' % LdapServersCSN[options.provider]) - for srv in LdapServersCSN: - if srv == options.provider: + long_output.append( + f'ContextCSN on LDAP server provider = {LdapServersCSN[options.provider]}') + for srv_name, srv_csn in LdapServersCSN.items(): + if srv_name == options.provider: continue - if not LdapServersCSN[srv]: - errors.append('ContextCSN of %s not found' % srv) - elif LdapServersCSN[srv] != LdapServersCSN[options.provider]: - errors.append('ContextCSN of %s not the same of provider' % srv) - long_output.append('ContextCSN on LDAP server %s = %s' % (srv, LdapServersCSN[srv])) + if not srv_csn: + errors.append(f'ContextCSN of {srv_name} not found') + elif srv_csn != LdapServersCSN[options.provider]: + errors.append( + f'ContextCSN of {srv_name} not the same of provider') + long_output.append( + f'ContextCSN on LDAP server {srv_name} = {srv_csn}') if not options.onlycheckcontextcsn: if not_found[options.consumer]: - errors.append("%s not found object(s) on consumer" % len(not_found[options.consumer])) - long_output.append("Object(s) not found on server %s (consumer) :" % options.consumer) + errors.append( + f'{len(not_found[options.consumer])} not found object(s) on ' + 'consumer') + long_output.append( + f'Object(s) not found on server {options.consumer} ' + '(consumer):') for obj in not_found[options.consumer]: - long_output.append(" - %s" % obj) + long_output.append(f' - {obj}') if not_found[options.provider]: - errors.append("%s not found object(s) on provider" % len(not_found[options.provider])) - long_output.append("Object(s) not found on server %s (provider) :" % options.provider) + errors.append( + f'{len(not_found[options.provider])} not found object(s) on ' + 'provider') + long_output.append( + f'Object(s) not found on server {options.provider} ' + '(provider):') for obj in not_found[options.provider]: - long_output.append(" - %s" % obj) + long_output.append(f' - {obj}') if not_sync[options.consumer]: - errors.append("%s not synchronized object(s) on consumer" % len(not_sync[options.consumer])) - long_output.append("Object(s) not synchronized on server %s (consumer) :" % options.consumer) + errors.append( + f'{len(not_sync[options.consumer])} not synchronized object(s) ' + 'on consumer') + long_output.append( + f'Object(s) not synchronized on server {options.consumer} ' + '(consumer):') for obj in not_sync[options.consumer]: - long_output.append(" - %s" % obj) + long_output.append(f' - {obj}') if errors: - print("CRITICAL: " + ', '.join(errors) + "\n\n" + "\n".join(long_output)) # pylint: disable=print-statement + print(f'CRITICAL: {", ".join(errors)}') + print('\n\n') + print("\n".join(long_output)) sys.exit(2) else: - print('OK: consumer and provider are synchronized') # pylint: disable=print-statement + print('OK: consumer and provider are synchronized') sys.exit(0) else: noerror = True for srv in servers: if not options.nocheckcontextcsn: if not LdapServersCSN[options.provider]: - logging.warning('ContextCSN of LDAP server provider could not be found') + logging.warning( + 'ContextCSN of LDAP server provider could not be found') noerror = False else: - for srv in LdapServersCSN: - if srv == options.provider: + for srv_name, srv_csn in LdapServersCSN.items(): + if srv_name == options.provider: continue - if not LdapServersCSN[srv]: - logging.warning('ContextCSN of %s not found', srv) + if not srv_csn: + logging.warning('ContextCSN of %s not found', srv_name) noerror = False - elif LdapServersCSN[srv] != LdapServersCSN[options.provider]: - logging.warning('ContextCSN of %s not the same of provider', srv) + elif srv_csn != LdapServersCSN[options.provider]: + logging.warning( + 'ContextCSN of %s not the same of provider', + srv_name) noerror = False if not options.onlycheckcontextcsn: diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..e44b810 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +ignore = E501