Code cleaning

This commit is contained in:
Benjamin Renard 2020-12-18 11:24:09 +01:00
parent 99aa93a497
commit d19d121843
2 changed files with 473 additions and 392 deletions

8
.pylintrc Normal file
View file

@ -0,0 +1,8 @@
[MESSAGES CONTROL]
disable=line-too-long,
missing-docstring,
invalid-name,
locally-disabled,
too-many-arguments,
too-many-branches,
redefined-outer-name,

View file

@ -26,483 +26,556 @@
# #
# This script could be use as Nagios plugin (-n argument) # This script could be use as Nagios plugin (-n argument)
# #
# Requirement : # Requirement:
# A single couple of DN and password able to connect to both server # A single couple of DN and password able to connect to both server
# and without restriction to retrieve objects from servers. # and without restriction to retrieve objects from servers.
# #
# Author : Benjamin Renard <brenard@easter-eggs.com> # Author: Benjamin Renard <brenard@easter-eggs.com>
# Date : Mon, 10 Dec 2012 18:04:24 +0100 # Date: Mon, 10 Dec 2012 18:04:24 +0100
# Source : http://git.zionetrix.net/check_syncrepl_extended # Source: http://git.zionetrix.net/check_syncrepl_extended
# #
import ldap import argparse
from ldap.controls import SimplePagedResultsControl
import ldap.modlist as modlist
import logging import logging
import sys import sys
import getpass import getpass
from optparse import OptionParser import ldap
from ldap import LDAPError # pylint: disable=no-name-in-module
from ldap.controls import SimplePagedResultsControl
import ldap.modlist as modlist
TOUCH_VALUE='%%TOUCH%%' TOUCH_VALUE = '%%TOUCH%%'
parser = OptionParser(version="%prog version 1.0\n\nDate : Mon, 10 Dec 2012 18:04:24 +0100\nAuthor : Benjamin Renard <brenard@easter-eggs.com>\nSource : http://git.zionetrix.net/check_syncrepl_extended") parser = argparse.ArgumentParser(
version="""%prog version 1.1
parser.add_option( "-p", "--provider", Date: Fri, 18 Dec 2020 10:48:45 +0100
dest="provider", Author: Benjamin Renard <brenard@easter-eggs.com>
action="store", Source: https://gogs.zionetrix.net/bn8/check_syncrepl_extended
type='string', """
help="LDAP provider URI (example : ldaps://ldapmaster.foo:636)") )
parser.add_option( "-c", "--consumer", parser.add_argument(
dest="consumer", "-p", "--provider",
action="store", dest="provider",
type='string', action="store",
help="LDAP consumer URI (example : ldaps://ldapslave.foo:636)") type=str,
help="LDAP provider URI (example: ldaps://ldapmaster.foo:636)"
)
parser.add_option( "-i", "--serverID", parser.add_argument(
dest="serverid", "-c", "--consumer",
action="store", dest="consumer",
type='int', action="store",
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#')", type=str,
default=False) help="LDAP consumer URI (example: ldaps://ldapslave.foo:636)"
)
parser.add_option( "-T", "--starttls", parser.add_argument(
dest="starttls", "-i", "--serverID",
action="store_true", dest="serverid",
help="Start TLS on LDAP provider/consumers connections", action="store",
default=False) 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#')",
default=False
)
parser.add_option( "-D", "--dn", parser.add_argument(
dest="dn", "-T", "--starttls",
action="store", dest="starttls",
type='string', action="store_true",
help="LDAP bind DN (example : uid=nagios,ou=sysaccounts,o=example") help="Start TLS on LDAP provider/consumers connections",
default=False
)
parser.add_option( "-P", "--pwd", parser.add_argument(
dest="pwd", "-D", "--dn",
action="store", dest="dn",
type='string', action="store",
help="LDAP bind password", type=str,
default=None) help="LDAP bind DN (example: uid=nagios,ou=sysaccounts,o=example"
)
parser.add_option( "-b", "--basedn", parser.add_argument(
dest="basedn", "-P", "--pwd",
action="store", dest="pwd",
type='string', action="store",
help="LDAP base DN (example : o=example)") type=str,
help="LDAP bind password",
default=None
)
parser.add_option( "-f", "--filter", parser.add_argument(
dest="filter", "-b", "--basedn",
action="store", dest="basedn",
type='string', action="store",
help="LDAP filter (default : (objectClass=*))", type=str,
default='(objectClass=*)') help="LDAP base DN (example: o=example)"
)
parser.add_option( "-d", "--debug", parser.add_argument(
dest="debug", "-f", "--filter",
action="store_true", dest="filterstr",
help="Debug mode", action="store",
default=False) type=str,
help="LDAP filter (default: (objectClass=*))",
default='(objectClass=*)'
)
parser.add_option( "-n", "--nagios", parser.add_argument(
dest="nagios", "-d", "--debug",
action="store_true", dest="debug",
help="Nagios check plugin mode", action="store_true",
default=False) help="Debug mode",
default=False
)
parser.add_option( "-q", "--quiet", parser.add_argument(
dest="quiet", "-n", "--nagios",
action="store_true", dest="nagios",
help="Quiet mode", action="store_true",
default=False) help="Nagios check plugin mode",
default=False
)
parser.add_option( "--no-check-certificate", parser.add_argument(
dest="nocheckcert", "-q", "--quiet",
action="store_true", dest="quiet",
help="Don't check the server certificate (Default : False)", action="store_true",
default=False) help="Quiet mode",
default=False
)
parser.add_option( "--no-check-contextCSN", parser.add_argument(
dest="nocheckcontextcsn", "--no-check-certificate",
action="store_true", dest="nocheckcert",
help="Don't check servers contextCSN (Default : False)", action="store_true",
default=False) help="Don't check the server certificate (Default: False)",
default=False
)
parser.add_option( "-a", "--attributes", parser.add_argument(
dest="attrs", "--no-check-contextCSN",
action="store_true", dest="nocheckcontextcsn",
help="Check attributes values (Default : check only entryCSN)", action="store_true",
default=False) help="Don't check servers contextCSN (Default: False)",
default=False
)
parser.add_option( "--exclude-attributes", parser.add_argument(
dest="excl_attrs", "-a", "--attributes",
action="store", dest="attrs",
type='string', action="store_true",
help="Don't check this attribut (only in attribute check mode)", help="Check attributes values (Default: check only entryCSN)",
default=None) default=False
)
parser.add_option( "--touch", parser.add_argument(
dest="touch", "--exclude-attributes",
action="store", dest="excl_attrs",
type='string', action="store",
help="Touch attribute giving in parameter to force resync a this LDAP object from provider. A value '%s' 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." % TOUCH_VALUE, type=str,
default=None) help="Don't check this attribut (only in attribute check mode)",
default=None
)
parser.add_option( "--replace-touch", parser.add_argument(
dest="replacetouch", "--touch",
action="store_true", dest="touch",
help="In touch mode, replace value instead of adding.", action="store",
default=False) type=str,
help="Touch attribute giving in parameter to force resync a this LDAP object from provider. A value '%s' 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." % TOUCH_VALUE,
default=None
)
parser.add_option( "--remove-touch-value", parser.add_argument(
dest="removetouchvalue", "--replace-touch",
action="store_true", dest="replacetouch",
help="In touch mode, remove touch value if present.", action="store_true",
default=False) help="In touch mode, replace value instead of adding.",
default=False
)
parser.add_option( "--page-size", parser.add_argument(
dest="page_size", "--remove-touch-value",
action="store", dest="removetouchvalue",
type='int', action="store_true",
help="Page size : if defined, paging control using LDAP v3 extended control will be enabled.", help="In touch mode, remove touch value if present.",
default=None) default=False
)
(options, args) = parser.parse_args() parser.add_argument(
"--page-size",
dest="page_size",
action="store",
type=int,
help="Page size: if defined, paging control using LDAP v3 extended control will be enabled.",
default=None
)
options = parser.parse_args()
if not options.provider or not options.consumer: if not options.provider or not options.consumer:
print "You must provide provider and customer URI" print "You must provide provider and customer URI"
if options.nagios: if options.nagios:
sys.exit(3) sys.exit(3)
sys.exit(1) sys.exit(1)
if not options.basedn: if not options.basedn:
print "You must provide base DN of connection to LDAP servers" print "You must provide base DN of connection to LDAP servers"
if options.nagios: if options.nagios:
sys.exit(3) sys.exit(3)
sys.exit(1) sys.exit(1)
if not 0 <= options.serverid <= 4095: if not 0 <= options.serverid <= 4095:
print "ServerID should be a integer value from 0 to 4095 (limited to 3 hexadecimal digits)." print "ServerID should be a integer value from 0 to 4095 (limited to 3 hexadecimal digits)."
if options.nagios: if options.nagios:
sys.exit(3) sys.exit(3)
sys.exit(1) sys.exit(1)
if options.touch and not options.attrs: if options.touch and not options.attrs:
logging.info('Force option attrs on touch mode') logging.info('Force option attrs on touch mode')
options.attrs=True options.attrs = True
if options.dn and options.pwd is None: if options.dn and options.pwd is None:
options.pwd=getpass.getpass() options.pwd = getpass.getpass()
excl_attrs=[] excl_attrs = []
if options.excl_attrs: if options.excl_attrs:
for ex in options.excl_attrs.split(','): for ex in options.excl_attrs.split(','):
excl_attrs.append(ex.strip()) excl_attrs.append(ex.strip())
FORMAT="%(asctime)s - %(levelname)s : %(message)s" FORMAT = "%(asctime)s - %(levelname)s: %(message)s"
if options.debug: if options.debug:
logging.basicConfig(level=logging.DEBUG,format=FORMAT) logging.basicConfig(level=logging.DEBUG, format=FORMAT)
ldap.set_option(ldap.OPT_DEBUG_LEVEL,0) ldap.set_option(ldap.OPT_DEBUG_LEVEL, 0) # pylint: disable=no-member
ldapmodule_trace_level = 1 ldapmodule_trace_level = 1
ldapmodule_trace_file = sys.stderr ldapmodule_trace_file = sys.stderr
elif options.nagios: elif options.nagios:
logging.basicConfig(level=logging.ERROR,format=FORMAT) logging.basicConfig(level=logging.ERROR, format=FORMAT)
elif options.quiet: elif options.quiet:
logging.basicConfig(level=logging.WARNING,format=FORMAT) logging.basicConfig(level=logging.WARNING, format=FORMAT)
else: else:
logging.basicConfig(level=logging.INFO,format=FORMAT) logging.basicConfig(level=logging.INFO, format=FORMAT)
class LdapServer(object): class LdapServer(object):
uri = "" uri = ""
dn = "" dn = ""
pwd = "" pwd = ""
start_tls = False start_tls = False
con = 0 con = 0
def __init__(self,uri,dn,pwd, start_tls=False, page_size=None): def __init__(self, uri, dn, pwd, start_tls=False, page_size=None):
self.uri = uri self.uri = uri
self.dn = dn self.dn = dn
self.pwd = pwd self.pwd = pwd
self.start_tls = start_tls self.start_tls = start_tls
self.page_size = page_size self.page_size = page_size
def connect(self): def connect(self):
if self.con == 0: if self.con == 0:
try: try:
con = ldap.initialize(self.uri) con = ldap.initialize(self.uri)
con.protocol_version = ldap.VERSION3 con.protocol_version = ldap.VERSION3 # pylint: disable=no-member
if self.start_tls: if self.start_tls:
con.start_tls_s() con.start_tls_s()
if self.dn: if self.dn:
con.simple_bind_s(self.dn,self.pwd) con.simple_bind_s(self.dn, self.pwd)
self.con = con self.con = con
return True except LDAPError:
except ldap.LDAPError, e: logging.error("LDAP Error", exc_info=True)
logging.error("LDAP Error : %s" % e) return False
return return True
def getContextCSN(self,basedn=False,serverid=False): def getContextCSN(self, basedn=False, serverid=False):
if not basedn: if not basedn:
basedn=self.dn basedn = self.dn
data=self.search(basedn,'(objectclass=*)',['contextCSN']) data = self.search(basedn, '(objectclass=*)', ['contextCSN'])
if len(data)>0: if data:
contextCSNs=data[0][0][1]['contextCSN'] contextCSNs = data[0][0][1]['contextCSN']
logging.debug('Found contextCSNs %s' % contextCSNs) logging.debug('Found contextCSNs %s', contextCSNs)
if serverid is False: if serverid is False:
return contextCSNs[0] return contextCSNs[0]
else: csnid = str(format(serverid, 'X')).zfill(3)
csnid=str(format(serverid, 'X')).zfill(3) sub = '#%s#' % csnid
sub='#%s#' % csnid CSN = [s for s in contextCSNs if sub in s]
CSN=[s for s in contextCSNs if sub in s] if not CSN:
if not CSN: logging.error(
logging.error("No contextCSN matching with ServerID %s (=%s) could be found." % (serverid,sub)) "No contextCSN matching with ServerID %s (=%s) could be found.",
return False serverid, sub
else: )
return CSN[0] return False
else: return CSN[0]
return False return False
def search(self,basedn,filter,attrs): def search(self, basedn, filterstr, attrs):
if self.page_size: if self.page_size:
return self.paged_search(basedn,filter,attrs) return self.paged_search(basedn, filterstr, attrs)
res_id = self.con.search(basedn,ldap.SCOPE_SUBTREE,filter,attrs) res_id = self.con.search(basedn, ldap.SCOPE_SUBTREE, filterstr, attrs) # pylint: disable=no-member
ret = [] ret = []
while 1: while 1:
res_type, res_data = self.con.result(res_id,0) res_type, res_data = self.con.result(res_id, 0)
if res_data == []: if res_data == []:
break break
else: else:
if res_type == ldap.RES_SEARCH_ENTRY: if res_type == ldap.RES_SEARCH_ENTRY: # pylint: disable=no-member
ret.append(res_data) ret.append(res_data)
return ret return ret
def paged_search(self,basedn,filter,attrs): def paged_search(self, basedn, filterstr, attrs):
ret = [] ret = []
page = 0 page = 0
pg_ctrl = SimplePagedResultsControl(True, self.page_size, '') pg_ctrl = SimplePagedResultsControl(True, self.page_size, '')
pg_oid = SimplePagedResultsControl.controlType while page == 0 or pg_ctrl.cookie:
while page == 0 or pg_ctrl.cookie: page += 1
page += 1 logging.debug('Page search: loading page %d', page)
logging.debug('Page search : loading page %d' % page) res_id = self.con.search_ext(
res_id = self.con.search_ext(basedn,ldap.SCOPE_SUBTREE,filter,attrs,serverctrls=[pg_ctrl]) basedn, ldap.SCOPE_SUBTREE, # pylint: disable=no-member
res_type, res_data, res_id, serverctrls = self.con.result3(res_id) filterstr, attrs,
for serverctrl in serverctrls: serverctrls=[pg_ctrl]
if serverctrl.controlType == pg_oid: )
pg_ctrl.cookie = serverctrl.cookie res_type, res_data, res_id, serverctrls = self.con.result3(res_id) # pylint: disable=unused-variable
for item in res_data: for serverctrl in serverctrls:
ret.append([item]) if serverctrl.controlType == SimplePagedResultsControl.controlType:
return ret pg_ctrl.cookie = serverctrl.cookie
break
for item in res_data:
ret.append([item])
return ret
def update_object(self,dn,old,new): def update_object(self, dn, old, new):
ldif = modlist.modifyModlist(old,new) ldif = modlist.modifyModlist(old, new)
if ldif == []: if ldif == []:
return True return True
try: try:
logging.debug('Update object %s : %s' % (dn,ldif)) logging.debug('Update object %s: %s', dn, ldif)
self.con.modify_s(dn,ldif) self.con.modify_s(dn, ldif)
return True return True
except ldap.LDAPError, e: except LDAPError:
logging.error('Error updating object %s : %s' % (dn,e)) logging.error('Error updating object %s', dn, exc_info=True)
return False return False
def get_attr(self,obj,attr): @staticmethod
if attr in obj[0][1]: def get_attr(obj, attr):
return obj[0][1][attr] if attr in obj[0][1]:
return [] return obj[0][1][attr]
return []
def touch_object(self,dn,attr,orig_value): def touch_object(self, dn, attr, orig_value):
old = {} old = {}
if orig_value: if orig_value:
old[attr] = orig_value old[attr] = orig_value
new = {} new = {}
if options.replacetouch: if options.replacetouch:
if not orig_value or TOUCH_VALUE not in orig_value: if not orig_value or TOUCH_VALUE not in orig_value:
new[attr] = [TOUCH_VALUE] new[attr] = [TOUCH_VALUE]
else: else:
new[attr] = list(orig_value) new[attr] = list(orig_value)
if orig_value or TOUCH_VALUE in orig_value: if orig_value or TOUCH_VALUE in orig_value:
new[attr].remove(TOUCH_VALUE) new[attr].remove(TOUCH_VALUE)
else: else:
new[attr].append(TOUCH_VALUE) new[attr].append(TOUCH_VALUE)
try: try:
logging.info('Touch object "%s" on attribute "%s" : %s => %s', dn, attr, old, new) logging.info(
if self.update_object(dn, old, new): 'Touch object "%s" on attribute "%s": %s => %s',
logging.info('Restore original value of attribute "%s" of object "%s"', attr, dn) dn, attr, old, new
if options.removetouchvalue and TOUCH_VALUE in old[attr]: )
old[attr].remove(TOUCH_VALUE) if self.update_object(dn, old, new):
self.update_object(dn, new, old) logging.info('Restore original value of attribute "%s" of object "%s"', attr, dn)
return True if options.removetouchvalue and TOUCH_VALUE in old[attr]:
except ldap.LDAPError: old[attr].remove(TOUCH_VALUE)
logging.error('Error touching object "%s"', dn, exc_info=True) self.update_object(dn, new, old)
return False return True
except LDAPError:
logging.error('Error touching object "%s"', dn, exc_info=True)
return False
if options.nocheckcert: if options.nocheckcert:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER) ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # pylint: disable=no-member
servers=[options.provider,options.consumer] servers = [options.provider, options.consumer]
LdapServers={} LdapServers = {}
LdapObjects={} LdapObjects = {}
LdapServersCSN={} LdapServersCSN = {}
for srv in servers: for srv in servers:
logging.info('Connect to %s' % srv) logging.info('Connect to %s', srv)
LdapServers[srv]=LdapServer(srv, options.dn, options.pwd, options.starttls, page_size=options.page_size) LdapServers[srv] = LdapServer(srv, options.dn, options.pwd, options.starttls, page_size=options.page_size)
if not LdapServers[srv].connect(): if not LdapServers[srv].connect():
if options.nagios: if options.nagios:
print "UNKWNON - Failed to connect to %s" % srv print "UNKWNON - Failed to connect to %s" % srv
sys.exit(3) sys.exit(3)
else: else:
sys.exit(1) sys.exit(1)
if not options.nocheckcontextcsn: 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])) logging.info('ContextCSN of %s: %s', srv, LdapServersCSN[srv])
logging.info('List objects from %s' % srv) logging.info('List objects from %s', srv)
LdapObjects[srv]={} LdapObjects[srv] = {}
if options.attrs: if options.attrs:
for obj in LdapServers[srv].search(options.basedn,options.filter,[]): for obj in LdapServers[srv].search(options.basedn, options.filterstr, []):
logging.debug('Found on %s : %s' % (srv,obj[0][0])) logging.debug('Found on %s: %s', srv, obj[0][0])
LdapObjects[srv][obj[0][0]]=obj[0][1] LdapObjects[srv][obj[0][0]] = obj[0][1]
else: else:
for obj in LdapServers[srv].search(options.basedn,options.filter,['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])) logging.debug(
LdapObjects[srv][obj[0][0]]=obj[0][1]['entryCSN'][0] 'Found on %s: %s / %s',
srv, obj[0][0], obj[0][1]['entryCSN'][0]
)
LdapObjects[srv][obj[0][0]] = obj[0][1]['entryCSN'][0]
logging.info('%s objects founds' % len(LdapObjects[srv])) logging.info('%s objects founds', len(LdapObjects[srv]))
not_found={} not_found = {}
not_sync={} not_sync = {}
for srv in servers: for srv in servers:
not_found[srv]=[] not_found[srv] = []
not_sync[srv]=[] not_sync[srv] = []
if options.attrs: 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: 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]: for obj in LdapObjects[options.provider]:
logging.debug('Check obj %s' % (obj)) logging.debug('Check obj %s', obj)
for srv in LdapObjects: for srv in LdapObjects:
if srv == options.provider: if srv == options.provider:
continue continue
if obj in LdapObjects[srv]: if obj in LdapObjects[srv]:
touch=False touch = False
if LdapObjects[options.provider][obj] != LdapObjects[srv][obj]: if LdapObjects[options.provider][obj] != LdapObjects[srv][obj]:
if options.attrs: if options.attrs:
attrs_list=[] attrs_list = []
for attr in LdapObjects[options.provider][obj]: for attr in LdapObjects[options.provider][obj]:
if attr in excl_attrs: if attr in excl_attrs:
continue continue
if attr not in LdapObjects[srv][obj]: if attr not in LdapObjects[srv][obj]:
attrs_list.append(attr) attrs_list.append(attr)
logging.debug("Obj %s not synchronized : %s not present on %s" % (obj,','.join(attrs_list),srv)) logging.debug(
touch=True "Obj %s not synchronized: %s not present on %s",
else: obj, ','.join(attrs_list), srv
LdapObjects[srv][obj][attr].sort() )
LdapObjects[options.provider][obj][attr].sort() touch = True
if LdapObjects[srv][obj][attr]!=LdapObjects[options.provider][obj][attr]: else:
attrs_list.append(attr) LdapObjects[srv][obj][attr].sort()
logging.debug("Obj %s not synchronized : %s not same value(s)" % (obj,','.join(attrs_list))) LdapObjects[options.provider][obj][attr].sort()
touch=True if LdapObjects[srv][obj][attr] != LdapObjects[options.provider][obj][attr]:
if len(attrs_list)>0: attrs_list.append(attr)
not_sync[srv].append("%s (%s)" % (obj,','.join(attrs_list))) logging.debug(
else: "Obj %s not synchronized: %s not same value(s)",
logging.debug("Obj %s not synchronized : %s <-> %s" % (obj,LdapObjects[options.provider][obj],LdapObjects[srv][obj])) obj, ','.join(attrs_list)
not_sync[srv].append(obj) )
if touch and options.touch: touch = True
orig_value=[] if attrs_list:
if options.touch in LdapObjects[options.provider][obj]: not_sync[srv].append("%s (%s)" % (obj, ','.join(attrs_list)))
orig_value=LdapObjects[options.provider][obj][options.touch] else:
LdapServers[options.provider].touch_object(obj,options.touch,orig_value) logging.debug(
else: "Obj %s not synchronized: %s <-> %s",
logging.debug('Obj %s : not found on %s' % (obj,srv)) obj, LdapObjects[options.provider][obj], LdapObjects[srv][obj]
not_found[srv].append(obj) )
if options.touch: not_sync[srv].append(obj)
orig_value=[] if touch and options.touch:
if options.touch in LdapObjects[options.provider][obj]: orig_value = []
orig_value=LdapObjects[options.provider][obj][options.touch] if options.touch in LdapObjects[options.provider][obj]:
LdapServers[options.provider].touch_object(obj,options.touch,orig_value) orig_value = LdapObjects[options.provider][obj][options.touch]
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)
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)
for obj in LdapObjects[options.consumer]: for obj in LdapObjects[options.consumer]:
logging.debug('Check obj %s of consumer' % obj) logging.debug('Check obj %s of consumer', obj)
if obj not in LdapObjects[options.provider]: if obj not in LdapObjects[options.provider]:
logging.debug('Obj %s : not found on provider' % obj) logging.debug('Obj %s: not found on provider', obj)
not_found[options.provider].append(obj) not_found[options.provider].append(obj)
if options.nagios: if options.nagios:
errors=[] errors = []
long_output=[] long_output = []
if not options.nocheckcontextcsn: if not options.nocheckcontextcsn:
if not LdapServersCSN[options.provider]: if not LdapServersCSN[options.provider]:
errors.append('ContextCSN of LDAP server provider could not be found') errors.append('ContextCSN of LDAP server provider could not be found')
else: else:
long_output.append('ContextCSN on LDAP server provider = %s' % LdapServersCSN[options.provider]) long_output.append('ContextCSN on LDAP server provider = %s' % LdapServersCSN[options.provider])
for srv in LdapServersCSN: for srv in LdapServersCSN:
if srv==options.provider: if srv == options.provider:
continue continue
if not LdapServersCSN[srv]: if not LdapServersCSN[srv]:
errors.append('ContextCSN of %s not found' % srv) errors.append('ContextCSN of %s not found' % srv)
elif LdapServersCSN[srv]!=LdapServersCSN[options.provider]: elif LdapServersCSN[srv] != LdapServersCSN[options.provider]:
errors.append('ContextCSN of %s not the same of provider' % srv) errors.append('ContextCSN of %s not the same of provider' % srv)
long_output.append('ContextCSN on LDAP server %s = %s' % (srv, LdapServersCSN[srv])) long_output.append('ContextCSN on LDAP server %s = %s' % (srv, LdapServersCSN[srv]))
if len(not_found[options.consumer])>0: if not_found[options.consumer]:
errors.append("%s not found object(s) on consumer" % len(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) long_output.append("Object(s) not found on server %s (consumer) :" % options.consumer)
for obj in not_found[options.consumer]: for obj in not_found[options.consumer]:
long_output.append(" - %s" % obj) long_output.append(" - %s" % obj)
if len(not_found[options.provider])>0: if not_found[options.provider]:
errors.append("%s not found object(s) on provider" % len(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) long_output.append("Object(s) not found on server %s (provider) :" % options.provider)
for obj in not_found[options.provider]: for obj in not_found[options.provider]:
long_output.append(" - %s" % obj) long_output.append(" - %s" % obj)
if len(not_sync[options.consumer])>0: if not_sync[options.consumer]:
errors.append("%s not synchronized object(s) on consumer" % len(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) long_output.append("Object(s) not synchronized on server %s (consumer) :" % options.consumer)
for obj in not_sync[options.consumer]: for obj in not_sync[options.consumer]:
long_output.append(" - %s" % obj) long_output.append(" - %s" % obj)
if len(errors)>0: if errors:
print "CRITICAL : " + ', '.join(errors) + "\n\n" + "\n".join(long_output) print "CRITICAL: " + ', '.join(errors) + "\n\n" + "\n".join(long_output)
sys.exit(2) sys.exit(2)
else: else:
print 'OK : consumer and provider are synchronized' print 'OK: consumer and provider are synchronized'
sys.exit(0) sys.exit(0)
else: else:
noerror=True noerror = True
for srv in servers: for srv in servers:
if not options.nocheckcontextcsn: if not options.nocheckcontextcsn:
if not LdapServersCSN[options.provider]: 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 noerror = False
else: else:
for srv in LdapServersCSN: for srv in LdapServersCSN:
if srv==options.provider: if srv == options.provider:
continue continue
if not LdapServersCSN[srv]: if not LdapServersCSN[srv]:
logging.warning('ContextCSN of %s not found' % srv) logging.warning('ContextCSN of %s not found', srv)
noerror=False noerror = False
elif LdapServersCSN[srv]!=LdapServersCSN[options.provider]: elif LdapServersCSN[srv] != LdapServersCSN[options.provider]:
logging.warning('ContextCSN of %s not the same of provider' % srv) logging.warning('ContextCSN of %s not the same of provider', srv)
noerror=False noerror = False
if len(not_found[srv])>0: if not_found[srv]:
logging.warning('Not found objects on %s :\n - %s' % (srv,'\n - '.join(not_found[srv]))) logging.warning(
noerror=False 'Not found objects on %s :\n - %s',
if len(not_sync[srv])>0: srv, '\n - '.join(not_found[srv])
logging.warning('Not sync objects on %s : %s' % (srv,'\n - '.join(not_sync[srv]))) )
noerror=False noerror = False
if not_sync[srv]:
if noerror: logging.warning(
logging.info('No sync problem detected') 'Not sync objects on %s: %s',
srv, '\n - '.join(not_sync[srv])
)
noerror = False
if noerror:
logging.info('No sync problem detected')