""" Some notable parameters: promise-timeout: Optional timeout (in seconds) for promise. timeout: Optional timeout (in seconds) for HTTP request. verify, ca-cert-file, cert-file, key-file: Optional SSL information. (See Python requests documentation.) http-code: (default 200) The expected response HTTP code. ignore-code: (default 0) If set to 1, ignore the response HTTP code. username, password: If supplied, enables basic HTTP authentication. """ from zope.interface import implementer from slapos.grid.promise import interface from slapos.grid.promise.generic import GenericPromise import requests @implementer(interface.IPromise) class RunPromise(GenericPromise): def __init__(self, config): super(RunPromise, self).__init__(config) # SR can set custom periodicity self.setPeriodicity(float(self.getConfig('frequency', 2))) def sense(self): """ Check if frontend URL is available. """ url = self.getConfig('url') # make default time a max of 5 seconds, a bit smaller than promise-timeout # and in the same time at least 1 second default_timeout = max( 1, min(5, int(self.getConfig('promise-timeout', 20)) - 1)) expected_http_code = int(self.getConfig('http-code', 200)) ca_cert_file = self.getConfig('ca-cert-file') cert_file = self.getConfig('cert-file') key_file = self.getConfig('key-file') verify = int(self.getConfig('verify', 0)) username = self.getConfig('username') password = self.getConfig('password') if int(self.getConfig('ignore-code', 0)) == 1: ignore_code = True else: ignore_code = False if ca_cert_file: verify = ca_cert_file elif verify: verify = True else: verify = False if key_file and cert_file: cert = (cert_file, key_file) else: cert = None if username and password: credentials = (username, password) request_type = "authenticated" else: credentials = None request_type = "non-authenticated" request_options = { 'allow_redirects': True, 'timeout': int(self.getConfig('timeout', default_timeout)), 'verify': verify, 'cert': cert, 'auth': credentials, } try: response = requests.get(url, **request_options) except requests.exceptions.SSLError as e: if 'certificate verify failed' in str(e): self.logger.error( "ERROR SSL verify failed while accessing %r", url) else: self.logger.error( "ERROR Unknown SSL error %r while accessing %r", e, url) except requests.ConnectionError as e: self.logger.error( "ERROR connection not possible while accessing %r", url) except Exception as e: self.logger.error("ERROR: %s", e) else: # Log a sensible message, depending on the request/response # parameters. if ignore_code: log = self.logger.info result = "succeeded" message = "return code ignored" elif response.status_code == expected_http_code: log = self.logger.info result = "succeeded" message = "returned expected code %d" % expected_http_code else: log = self.logger.error result = "failed" message = "returned %d, expected %d" % (response.status_code, expected_http_code) log("%s request to %r %s (%s)", request_type, url, result, message) def anomaly(self): return self._test(result_count=3, failure_amount=3)