Benjamin Renard commited on 2013-05-15 15:32:27
Showing 1 changed files, with 55 additions and 0 deletions.
... | ... |
@@ -24,11 +24,14 @@ |
24 | 24 |
# |
25 | 25 |
|
26 | 26 |
import ldap |
27 |
+import ldap.modlist as modlist |
|
27 | 28 |
import logging |
28 | 29 |
import sys |
29 | 30 |
|
30 | 31 |
from optparse import OptionParser |
31 | 32 |
|
33 |
+TOUCH_VALUE='%%TOUCH%%' |
|
34 |
+ |
|
32 | 35 |
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") |
33 | 36 |
|
34 | 37 |
parser.add_option( "-p", "--provider", |
... | ... |
@@ -111,6 +114,13 @@ parser.add_option( "--exclude-attributes", |
111 | 114 |
help="Don't check this attribut (only in attribute check mode)", |
112 | 115 |
default=None) |
113 | 116 |
|
117 |
+parser.add_option( "--touch", |
|
118 |
+ dest="touch", |
|
119 |
+ action="store", |
|
120 |
+ type='string', |
|
121 |
+ 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, |
|
122 |
+ default=None) |
|
123 |
+ |
|
114 | 124 |
|
115 | 125 |
(options, args) = parser.parse_args() |
116 | 126 |
|
... | ... |
@@ -126,6 +136,13 @@ if not options.basedn: |
126 | 136 |
print "You must provide base DN of connection to LDAP servers" |
127 | 137 |
sys.exit(1) |
128 | 138 |
|
139 |
+if options.touch and not options.attrs: |
|
140 |
+ logging.info('Force option attrs on touch mode') |
|
141 |
+ options.attrs=True |
|
142 |
+elif options.touch and options.nagios: |
|
143 |
+ logging.error('Touch mode and Nagios mode not compatible') |
|
144 |
+ sys.exit(1) |
|
145 |
+ |
|
129 | 146 |
excl_attrs=[] |
130 | 147 |
if options.excl_attrs: |
131 | 148 |
for ex in options.excl_attrs.split(','): |
... | ... |
@@ -190,6 +207,36 @@ class LdapServer(object): |
190 | 207 |
ret.append(res_data) |
191 | 208 |
return ret |
192 | 209 |
|
210 |
+ def update_object(self,dn,old,new): |
|
211 |
+ ldif = modlist.modifyModlist(old,new) |
|
212 |
+ if ldif == []: |
|
213 |
+ return True |
|
214 |
+ try: |
|
215 |
+ logging.debug('Update object %s : %s' % (dn,ldif)) |
|
216 |
+ self.con.modify_s(dn,ldif) |
|
217 |
+ return True |
|
218 |
+ except ldap.LDAPError, e: |
|
219 |
+ logging.error('Error updating object %s : %s' % (dn,e)) |
|
220 |
+ return False |
|
221 |
+ |
|
222 |
+ def get_attr(self,obj,attr): |
|
223 |
+ if attr in obj[0][1]: |
|
224 |
+ return obj[0][1][attr] |
|
225 |
+ return [] |
|
226 |
+ |
|
227 |
+ def touch_object(self,dn,attr,orig_value): |
|
228 |
+ new_value=list(orig_value) |
|
229 |
+ new_value.append(TOUCH_VALUE) |
|
230 |
+ try: |
|
231 |
+ logging.info('Add value "%s" to attribute %s of object %s' % (TOUCH_VALUE,attr,dn)) |
|
232 |
+ if self.update_object(dn,{attr: orig_value}, {attr: new_value}): |
|
233 |
+ logging.info('Remove value "%s" to attribute %s of object %s' % (TOUCH_VALUE,attr,dn)) |
|
234 |
+ self.update_object(dn,{attr: new_value}, {attr: orig_value}) |
|
235 |
+ return True |
|
236 |
+ except ldap.LDAPError, e: |
|
237 |
+ logging.error('Error touching object %s : %s' % (dn,e)) |
|
238 |
+ return False |
|
239 |
+ |
|
193 | 240 |
if options.nocheckcert: |
194 | 241 |
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER) |
195 | 242 |
|
... | ... |
@@ -246,6 +293,7 @@ for obj in LdapObjects[options.provider]: |
246 | 293 |
if srv == options.provider: |
247 | 294 |
continue |
248 | 295 |
if obj in LdapObjects[srv]: |
296 |
+ touch=False |
|
249 | 297 |
if LdapObjects[options.provider][obj] != LdapObjects[srv][obj]: |
250 | 298 |
if options.attrs: |
251 | 299 |
attrs_list=[] |
... | ... |
@@ -255,17 +303,24 @@ for obj in LdapObjects[options.provider]: |
255 | 303 |
if attr not in LdapObjects[srv][obj]: |
256 | 304 |
attrs_list.append(attr) |
257 | 305 |
logging.debug("Obj %s not synchronized : %s not present on %s" % (obj,','.join(attrs_list),srv)) |
306 |
+ touch=True |
|
258 | 307 |
else: |
259 | 308 |
LdapObjects[srv][obj][attr].sort() |
260 | 309 |
LdapObjects[options.provider][obj][attr].sort() |
261 | 310 |
if LdapObjects[srv][obj][attr]!=LdapObjects[options.provider][obj][attr]: |
262 | 311 |
attrs_list.append(attr) |
263 | 312 |
logging.debug("Obj %s not synchronized : %s not same value(s)" % (obj,','.join(attrs_list))) |
313 |
+ touch=True |
|
264 | 314 |
if len(attrs_list)>0: |
265 | 315 |
not_sync[srv].append("%s (%s)" % (obj,','.join(attrs_list))) |
266 | 316 |
else: |
267 | 317 |
logging.debug("Obj %s not synchronized : %s <-> %s" % (obj,LdapObjects[options.provider][obj],LdapObjects[srv][obj])) |
268 | 318 |
not_sync[srv].append(obj) |
319 |
+ if touch and options.touch: |
|
320 |
+ orig_value=[] |
|
321 |
+ if options.touch in LdapObjects[options.provider][obj]: |
|
322 |
+ orig_value=LdapObjects[options.provider][obj][options.touch] |
|
323 |
+ LdapServers[options.provider].touch_object(obj,options.touch,orig_value) |
|
269 | 324 |
else: |
270 | 325 |
logging.debug('Obj %s : not found on %s' % (obj,srv)) |
271 | 326 |
not_found[srv].append(obj) |
272 | 327 |