Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
                })
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
 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
Ejemplo n.º 8
0
 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))
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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