<s> import errno <EOL> import httplib <EOL> import os <EOL> import select <EOL> import signal <EOL> import time <EOL> class HttpCheck ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , method = '<STR_LIT:GET>' , url = '<STR_LIT:/>' , body = None , headers = { } , <EOL> port = None , useHttps = False , validStatusCodes = [ <NUM_LIT:200> , <NUM_LIT> ] ) : <EOL> self . method = method <EOL> self . url = url <EOL> self . body = body <EOL> self . headers = headers <EOL> if not port : <EOL> port = <NUM_LIT> if not useHttps else <NUM_LIT> <EOL> self . port = port <EOL> self . useHttps = useHttps <EOL> self . validStatusCodes = validStatusCodes <EOL> def check ( self , ipaddr ) : <EOL> if self . useHttps : <EOL> connection = httplib . HTTPSConnection ( ipaddr , self . port ) <EOL> else : <EOL> connection = httplib . HTTPConnection ( ipaddr , self . port ) <EOL> try : <EOL> connection . request ( self . method , self . url , self . body , self . headers ) <EOL> response = connection . getresponse ( ) <EOL> return response . status in self . validStatusCodes <EOL> except : <EOL> return False <EOL> class TickTimer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , interval , timeout , retry ) : <EOL> self . interval = interval <EOL> self . timeout = timeout <EOL> self . retry = retry <EOL> self . last = <NUM_LIT:0> <EOL> def getNextCheckTime ( self ) : <EOL> if self . last == <NUM_LIT:0> : <EOL> self . last = time . time ( ) + <NUM_LIT:1> <EOL> return self . last <EOL> self . last += self . interval <EOL> if self . last < time . time ( ) : <EOL> self . last = time . time ( ) <EOL> return self . last <EOL> def getCheckTimeout ( self ) : <EOL> return self . timeout <EOL> def getRetry ( self ) : <EOL> return self . retry <EOL> def boundedCheck ( target , check , timer , logger ) : <EOL> """<STR_LIT>""" <EOL> timeout = timer . getCheckTimeout ( ) <EOL> deadline = time . time ( ) + timeout <EOL> logger . debug ( '<STR_LIT>' <EOL> . format ( check , target , timeout ) ) <EOL> pipe = os . pipe ( ) <EOL> def sigchld ( sig , frame ) : <EOL> try : <EOL> os . write ( pipe [ <NUM_LIT:1> ] , '<STR_LIT:U+0020>' ) <EOL> except : <EOL> pass <EOL> signal . signal ( signal . SIGCHLD , sigchld ) <EOL> pid = os . fork ( ) <EOL> if pid : <EOL> while time . time ( ) < deadline : <EOL> timeout = max ( <NUM_LIT:0> , deadline - time . time ( ) ) <EOL> try : <EOL> rfds , wfds , efds = select . select ( [ pipe [ <NUM_LIT:0> ] ] , [ ] , [ ] , timeout ) <EOL> except select . error as err : <EOL> if err . args [ <NUM_LIT:0> ] == errno . EINTR : <EOL> continue <EOL> if rfds : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> childpid , status = os . wait ( ) <EOL> logger . debug ( '<STR_LIT>' . format ( status ) ) <EOL> retval = ( status == <NUM_LIT:0> ) <EOL> else : <EOL> logger . info ( '<STR_LIT>' ) <EOL> os . kill ( pid , signal . SIGKILL ) <EOL> logger . debug ( '<STR_LIT>' ) <EOL> os . wait ( ) <EOL> retval = False <EOL> os . close ( pipe [ <NUM_LIT:0> ] ) <EOL> os . close ( pipe [ <NUM_LIT:1> ] ) <EOL> logger . debug ( '<STR_LIT>' . format ( retval ) ) <EOL> return retval <EOL> else : <EOL> try : <EOL> if check . check ( target ) : <EOL> exit ( <NUM_LIT:0> ) <EOL> else : <EOL> exit ( <NUM_LIT:1> ) <EOL> except Exception : <EOL> exit ( <NUM_LIT:2> ) <EOL> def retryBoundedCheck ( target , check , timer , logger ) : <EOL> retry = timer . getRetry ( ) <EOL> failed = <NUM_LIT:0> <EOL> while True : <EOL> if boundedCheck ( target , check , timer , logger ) : <EOL> if failed : <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( failed , target ) ) <EOL> return True <EOL> failed += <NUM_LIT:1> <EOL> if failed >= retry : <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( failed , target ) ) <EOL> return False <EOL> def run ( fqdns , ip_addresses , dns , check , timer , logger ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( fqdns , basestring ) : <EOL> fqdns = [ fqdns ] <EOL> if isinstance ( ip_addresses , basestring ) : <EOL> ip_addresses = [ ip_addresses ] <EOL> logger . info ( '<STR_LIT>' ) <EOL> while True : <EOL> now = time . time ( ) <EOL> nextCheck = timer . getNextCheckTime ( ) <EOL> if now > nextCheck : <EOL> logger . warning ( '<STR_LIT>' <EOL> . format ( now - nextCheck ) ) <EOL> while time . time ( ) < nextCheck : <EOL> wait = nextCheck - time . time ( ) <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( wait ) ) <EOL> time . sleep ( wait ) <EOL> for fqdn in fqdns : <EOL> logger . debug ( '<STR_LIT>' <EOL> . format ( fqdn ) ) <EOL> try : <EOL> records = dns . get_a_records ( fqdn ) <EOL> except Exception as e : <EOL> logger . error ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( fqdn , e ) ) <EOL> continue <EOL> else : <EOL> logger . debug ( '<STR_LIT>' <EOL> . format ( records ) ) <EOL> logger . debug ( '<STR_LIT>' ) <EOL> for ip_addr in ip_addresses : <EOL> if not retryBoundedCheck ( ip_addr , check , timer , logger ) : <EOL> if ip_addr in records : <EOL> if len ( records ) < <NUM_LIT:2> : <EOL> logger . error ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , fqdn ) ) <EOL> else : <EOL> logger . error ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , fqdn ) ) <EOL> try : <EOL> n_deleted = dns . delete_a_record ( fqdn , ip_addr ) <EOL> except Exception as e : <EOL> logger . error ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , fqdn , e ) ) <EOL> else : <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , n_deleted ) ) <EOL> break <EOL> else : <EOL> logger . info ( '<STR_LIT>' <EOL> . format ( ip_addr ) ) <EOL> else : <EOL> if ip_addr in records : <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr ) ) <EOL> else : <EOL> logger . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , fqdn ) ) <EOL> try : <EOL> dns . add_a_record ( fqdn , ip_addr ) <EOL> except Exception as e : <EOL> logger . error ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr , fqdn , e ) ) <EOL> else : <EOL> logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( ip_addr ) ) </s>
