def test_keystone_should_be_singleton(self): keystone_1 = keystone.Keystone({}) keystone_2 = keystone.Keystone({}) keystone_3 = keystone.Keystone({}) self.assertTrue(keystone_1 is keystone_2) self.assertTrue(keystone_1 is keystone_3)
def __init__(self, name, init_config, agent_config, instances=None): self._socket_errors = set() self._response_not_ready = set() self._general_exception = set() self._invalid_token = set() self._warn_msg = set() super(HTTPCheck, self).__init__(name, init_config, agent_config, instances) # init the keystone client if instance has use_keystone self._api_config = cfg.Config().get_config('Api') self._ksclients = {} init_keystone_config = init_config.get('keystone_config', None) for instance in instances: addr, username, password, timeout, headers, response_time, \ disable_ssl_validation, use_keystone, keystone_config, \ instance_name = self._load_http_conf(instance) if use_keystone: # keystone is a singleton. It will be initialized once, # the first config instance used. if init_keystone_config: ksclient = keystone.Keystone(init_keystone_config) elif keystone_config: # Using Keystone config in each instance is deprecated # in Rocky. ksclient = keystone.Keystone(keystone_config) else: ksclient = keystone.Keystone(self._api_config) self._ksclients[instance_name] = ksclient
def test_should_call_service_catalog_for_endpoint(self): keystone.Keystone.instance = None with mock.patch('keystoneauth1.identity.Password') as password, \ mock.patch('keystoneauth1.session.Session') as session, \ mock.patch('keystoneclient.discover.Discover') as discover: client = mock.Mock() discover.return_value = d = mock.Mock() d.create_client = mock.Mock(return_value=client) config = base_config.get_config('Api') config.update({ 'url': None, 'service_type': self.default_service_type, 'endpoint_type': self.default_endpoint_type, 'region_name': self.default_region_name }) k = keystone.Keystone(config) k.get_monasca_url() password.assert_called_once() session.assert_called_once() discover.assert_called_once() client.auth_ref.service_catalog.url_for.assert_called_once_with( **{ 'service_type': self.default_service_type, 'interface': self.default_endpoint_type, 'region_name': self.default_region_name })
def test_should_use_url_from_config_if_catalog_config_missing(self): keystone.Keystone.instance = None with mock.patch('keystoneauth1.identity.Password') as password, \ mock.patch('keystoneauth1.session.Session') as session, \ mock.patch('keystoneclient.discover.Discover') as discover: client = mock.Mock() discover.return_value = d = mock.Mock() d.create_client = mock.Mock(return_value=client) monasca_url = mock.NonCallableMock() config = base_config.get_config('Api') config.update({ 'url': monasca_url, 'service_type': None, 'endpoint_type': None, 'region_name': None }) k = keystone.Keystone(config) k.get_monasca_url() password.assert_not_called() session.assert_not_called() discover.assert_not_called() client.auth_ref.service_catalog.url_for.assert_not_called()
def __init__(self, config): """Initialize Mon api client connection.""" self.config = config self.url = config['url'] self.api_version = '2_0' self.keystone = keystone.Keystone(config) self.mon_client = None self._failure_reason = None self._resume_time = None self._log_interval_remaining = 1 self._current_number_measurements = 0 self.max_buffer_size = int(config['max_buffer_size']) self.max_measurement_buffer_size = int( config['max_measurement_buffer_size']) if self.max_buffer_size > -1: log.debug("'max_buffer_size' is deprecated. Please use" " 'max_measurement_buffer_size' instead") if self.max_measurement_buffer_size > -1: log.debug("Overriding 'max_buffer_size' option with new" " 'max_measurment_buffer_size' option") self.max_buffer_size = -1 self.backlog_send_rate = int(config['backlog_send_rate']) if self.max_buffer_size > -1: self.message_queue = collections.deque(maxlen=self.max_buffer_size) else: self.message_queue = collections.deque() self.write_timeout = int(config['write_timeout']) # 'amplifier' is completely optional and may not exist in the config try: self.amplifier = int(config['amplifier']) except KeyError: self.amplifier = None
def __init__(self, name, init_config, agent_config, instances=None): super(HTTPCheck, self).__init__(name, init_config, agent_config, instances) # init the keystone client if instance has use_keystone self._api_config = cfg.Config().get_config('Api') self._ksclients = {} for instance in instances: addr, username, password, timeout, headers, response_time, \ disable_ssl_validation, use_keystone, keystone_config, \ instance_name = self._load_http_conf(instance) if use_keystone: # keystone is a singleton. It will be initialized once, # the first config instance used. if keystone_config: ksclient = keystone.Keystone(keystone_config) else: ksclient = keystone.Keystone(self._api_config) self._ksclients[instance_name] = ksclient
def _get_mon_client(self): k = keystone.Keystone(self._config) endpoint = k.get_monasca_url() session = k.get_session() c = client.Client(api_version=self._api_version, endpoint=endpoint, session=session, timeout=self.write_timeout, **keystone.get_args(self._config)) return c
def _get_mon_client(self): try: k = keystone.Keystone(self._config) endpoint = k.get_monasca_url() session = k.get_session() c = client.Client(api_version=self._api_version, endpoint=endpoint, session=session, timeout=self.write_timeout, **keystone.get_args(self._config)) return c except keystoneauth_exception.ClientException as ex: log.error('Failed to initialize Monasca client. {}'.format(ex))
def test_should_init_client_just_once(self): keystone.Keystone.instance = None k = keystone.Keystone(config=base_config.get_config('Api')) client = mock.Mock() with mock.patch('monasca_agent.common.keystone.get_client') as gc: gc.return_value = client for _ in range(random.randint(5, 50)): k._init_client() self.assertIsNotNone(k._keystone_client) self.assertEqual(client, k._keystone_client) gc.assert_called_once()
def __init__(self, config): """Initialize Mon api client connection.""" self.config = config self.url = config['url'] self.api_version = '2_0' self.keystone = keystone.Keystone(config) self.mon_client = None self._failure_reason = None self._resume_time = None self.max_buffer_size = int(config['max_buffer_size']) self.backlog_send_rate = int(config['backlog_send_rate']) self.message_queue = collections.deque(maxlen=self.max_buffer_size) # 'amplifier' is completely optional and may not exist in the config try: self.amplifier = int(config['amplifier']) except KeyError: self.amplifier = None
def _http_check(self, instance): addr, username, password, timeout, headers, response_time, disable_ssl_validation, use_keystone, keystone_config = self._load_http_conf( instance) config = cfg.Config() api_config = config.get_config('Api') dimensions = self._set_dimensions({'url': addr}, instance) start = time.time() done = False retry = False while not done or retry: if use_keystone: if keystone_config: key = keystone.Keystone(keystone_config) else: key = keystone.Keystone(api_config) token = key.get_token() if token: headers["X-Auth-Token"] = token headers["Content-type"] = "application/json" else: error_string = """Unable to get token. Keystone API server may be down. Skipping check for {0}""".format(addr) self.log.warning(error_string) return False, error_string try: self.log.debug("Connecting to %s" % addr) if disable_ssl_validation: self.warning( "Skipping SSL certificate validation for %s based on configuration" % addr) h = Http( timeout=timeout, disable_ssl_certificate_validation=disable_ssl_validation) if username is not None and password is not None: h.add_credentials(username, password) resp, content = h.request(addr, "GET", headers=headers) except (socket.timeout, HttpLib2Error, socket.error) as e: length = int((time.time() - start) * 1000) error_string = '{0} is DOWN, error: {1}. Connection failed after {2} ms'.format( addr, str(e), length) self.log.info(error_string) return False, error_string except httplib.ResponseNotReady as e: length = int((time.time() - start) * 1000) error_string = '{0} is DOWN, error: {1}. Network is not routable after {2} ms'.format( addr, repr(e), length) self.log.info(error_string) return False, error_string except Exception as e: length = int((time.time() - start) * 1000) error_string = '{0} is DOWN, error: {1}. Connection failed after {2} ms'.format( addr, str(e), length) self.log.error( 'Unhandled exception {0}. Connection failed after {1} ms'. format(str(e), length)) return False, error_string if response_time: # Stop the timer as early as possible running_time = time.time() - start self.gauge('http_response_time', running_time, dimensions=dimensions) if int(resp.status) >= 400: if use_keystone and int(resp.status) == 401: if retry: error_string = '{0} is DOWN, unable to get a valid token to connect with'.format( addr) self.log.error(error_string) return False, error_string else: # Get a new token and retry self.log.info( "Token expired, getting new token and retrying...") retry = True key.refresh_token() continue else: error_string = '{0} is DOWN, error code: {1}'.format( addr, str(resp.status)) self.log.info(error_string) return False, error_string done = True return True, content
def _check(self, instance): addr, username, password, timeout, headers, response_time, disable_ssl_validation, pattern, use_keystone = self._load_conf( instance) config = cfg.Config() api_config = config.get_config('Api') content = '' dimensions = self._set_dimensions({'url': addr}, instance) start = time.time() done = False retry = False while not done or retry: if use_keystone: key = keystone.Keystone(api_config) token = key.get_token() if token: headers["X-Auth-Token"] = token headers["Content-type"] = "application/json" else: self.log.warning("""Unable to get token. Keystone API server may be down. Skipping check for {0}""".format(addr)) return try: self.log.debug("Connecting to %s" % addr) if disable_ssl_validation: self.warning( "Skipping SSL certificate validation for %s based on configuration" % addr) h = Http(timeout=timeout, disable_ssl_certificate_validation=disable_ssl_validation) if username is not None and password is not None: h.add_credentials(username, password) resp, content = h.request(addr, "GET", headers=headers) except socket.timeout as e: length = int((time.time() - start) * 1000) self.log.info( "%s is DOWN, error: %s. Connection failed after %s ms" % (addr, str(e), length)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error: %s. Connection failed after %s ms" % ( addr, str(e), length) except HttpLib2Error as e: length = int((time.time() - start) * 1000) self.log.info( "%s is DOWN, error: %s. Connection failed after %s ms" % (addr, str(e), length)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error: %s. Connection failed after %s ms" % ( addr, str(e), length) except socket.error as e: length = int((time.time() - start) * 1000) self.log.info("%s is DOWN, error: %s. Connection failed after %s ms" % ( addr, repr(e), length)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error: %s. Connection failed after %s ms" % ( addr, str(e), length) except httplib.ResponseNotReady as e: length = int((time.time() - start) * 1000) self.log.info("%s is DOWN, error: %s. Network is not routable after %s ms" % ( addr, repr(e), length)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error: %s. Network is not routable after %s ms" % ( addr, str(e), length) except Exception as e: length = int((time.time() - start) * 1000) self.log.error( "Unhandled exception %s. Connection failed after %s ms" % (str(e), length)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error: %s. Connection failed after %s ms" % ( addr, str(e), length) if response_time: # Stop the timer as early as possible running_time = time.time() - start self.gauge('http_response_time', running_time, dimensions=dimensions) # TODO(dschroeder): Save/send content data when supported by API if int(resp.status) >= 400: if use_keystone and int(resp.status) == 401: if retry: self.log.error("%s is DOWN, unable to get a valid token to connect with" % (addr)) return services_checks.Status.DOWN, "%s is DOWN, unable to get a valid token to connect with" % ( addr) else: # Get a new token and retry self.log.info("Token expired, getting new token and retrying...") retry = True key.refresh_token() continue else: self.log.info("%s is DOWN, error code: %s" % (addr, str(resp.status))) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "%s is DOWN, error code: %s" % (addr, str(resp.status)) if pattern is not None: if re.search(pattern, content, re.DOTALL): self.log.debug("Pattern match successful") else: self.log.info("Pattern match failed! '%s' not in '%s'" % (pattern, content)) self.gauge('http_status', 1, dimensions=dimensions) return services_checks.Status.DOWN, "Pattern match failed! '%s' not in '%s'" % ( pattern, content) self.log.debug("%s is UP" % addr) self.gauge('http_status', 0, dimensions=dimensions) done = True return services_checks.Status.UP, "%s is UP" % addr