Пример #1
0
 def _get_events(self):
     """Get the list of events."""
     events, changed_container_ids = self.docker_util.get_events()
     if changed_container_ids and self._service_discovery:
         get_sd_backend(
             self.agentConfig).update_checks(changed_container_ids)
     return events
Пример #2
0
 def _get_events(self):
     """Get the list of events."""
     events, changed_container_ids = self.docker_util.get_events()
     if not self._disable_net_metrics:
         self._invalidate_network_mapping_cache(events)
     if changed_container_ids and self._service_discovery:
         get_sd_backend(
             self.agentConfig).update_checks(changed_container_ids)
     return events
Пример #3
0
 def _get_events(self):
     """Get the list of events."""
     events, changed_container_ids = self.docker_util.get_events()
     if not self._disable_net_metrics:
         self._invalidate_network_mapping_cache(events)
     if changed_container_ids and self._service_discovery:
         get_sd_backend(self.agentConfig).update_checks(changed_container_ids)
     if changed_container_ids:
         self.metadata_collector.invalidate_cache(events)
         if Platform.is_nomad():
             self.nomadutil.invalidate_cache(events)
         elif Platform.is_ecs_instance():
             self.ecsutil.invalidate_cache(events)
     return events
Пример #4
0
 def _get_events(self):
     """Get the list of events."""
     events, changed_container_ids = self.docker_util.get_events()
     if not self._disable_net_metrics:
         self._invalidate_network_mapping_cache(events)
     if changed_container_ids and self._service_discovery:
         get_sd_backend(self.agentConfig).update_checks(changed_container_ids)
     if changed_container_ids:
         self.metadata_collector.invalidate_cache(events)
         if Platform.is_nomad():
             self.nomadutil.invalidate_cache(events)
         elif Platform.is_ecs_instance():
             self.ecsutil.invalidate_cache(events)
     return events
Пример #5
0
    def test_render_template(self):
        """Test _render_template"""
        valid_configs = [
            (({}, {'host': '%%host%%'}, {'host': 'foo'}),
             ({}, {'host': 'foo'})),
            (({}, {'host': '%%host%%', 'port': '%%port%%'}, {'host': 'foo', 'port': '1337'}),
             ({}, {'host': 'foo', 'port': '1337'})),
            (({'foo': '%%bar%%'}, {}, {'bar': 'w00t'}),
             ({'foo': 'w00t'}, {})),
            (({'foo': '%%bar%%'}, {'host': '%%host%%'}, {'bar': 'w00t', 'host': 'localhost'}),
             ({'foo': 'w00t'}, {'host': 'localhost'}))
        ]

        invalid_configs = [
            ({}, {'host': '%%host%%'}, {}),  # no value to use
            ({}, {'host': '%%host%%'}, {'port': 42}),  # the variable name doesn't match
            ({'foo': '%%bar%%'}, {'host': '%%host%%'}, {'host': 'foo'})  # not enough value/no matching var name
        ]

        with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
            with mock.patch.object(EtcdStore, 'get_client', return_value=None):
                with mock.patch.object(ConsulStore, 'get_client', return_value=None):
                    for agentConfig in self.agentConfigs:
                        sd_backend = get_sd_backend(agentConfig=agentConfig)
                        for tpl, res in valid_configs:
                            init, instance, variables = tpl
                            config = sd_backend._render_template(init, instance, variables)
                            self.assertEquals(config, res)
                        for init, instance, variables in invalid_configs:
                            config = sd_backend._render_template(init, instance, variables)
                            self.assertEquals(config, None)
                            clear_singletons(agentConfig)
Пример #6
0
    def test_render_template(self):
        """Test _render_template"""
        valid_configs = [
            (({}, {'host': '%%host%%'}, {'host': 'foo'}),
             ({}, {'host': 'foo'})),
            (({}, {'host': '%%host%%', 'port': '%%port%%'}, {'host': 'foo', 'port': '1337'}),
             ({}, {'host': 'foo', 'port': '1337'})),
            (({'foo': '%%bar%%'}, {}, {'bar': 'w00t'}),
             ({'foo': 'w00t'}, {})),
            (({'foo': '%%bar%%'}, {'host': '%%host%%'}, {'bar': 'w00t', 'host': 'localhost'}),
             ({'foo': 'w00t'}, {'host': 'localhost'}))
        ]

        invalid_configs = [
            ({}, {'host': '%%host%%'}, {}),  # no value to use
            ({}, {'host': '%%host%%'}, {'port': 42}),  # the variable name doesn't match
            ({'foo': '%%bar%%'}, {'host': '%%host%%'}, {'host': 'foo'})  # not enough value/no matching var name
        ]

        with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
            with mock.patch.object(EtcdStore, 'get_client', return_value=None):
                with mock.patch.object(ConsulStore, 'get_client', return_value=None):
                    for agentConfig in self.agentConfigs:
                        sd_backend = get_sd_backend(agentConfig=agentConfig)
                        for tpl, res in valid_configs:
                            init, instance, variables = tpl
                            config = sd_backend._render_template(init, instance, variables)
                            self.assertEquals(config, res)
                        for init, instance, variables in invalid_configs:
                            config = sd_backend._render_template(init, instance, variables)
                            self.assertEquals(config, None)
                            clear_singletons(agentConfig)
Пример #7
0
    def test_get_host(self, mock_check_yaml, mock_get):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP':
                    '127.0.0.1',
                    'containerStatuses': [{
                        'containerID':
                        'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'
                    }]
                }
            }]
        }

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, expected_ip, _ in self.container_inspects:
            with mock.patch.object(AbstractConfigStore,
                                   '__init__',
                                   return_value=None):
                with mock.patch('utils.dockerutil.DockerUtil.client',
                                return_value=None):
                    with mock.patch('utils.kubeutil.get_conf_path',
                                    return_value=None):
                        sd_backend = get_sd_backend(
                            agentConfig=self.auto_conf_agentConfig)
                        self.assertEqual(sd_backend._get_host(c_ins),
                                         expected_ip)
                        clear_singletons(self.auto_conf_agentConfig)
Пример #8
0
 def _get_events(self):
     """Get the list of events."""
     events, conf_reload_set = self.docker_util.get_events()
     if conf_reload_set and self._service_discovery:
         get_sd_backend(
             self.agentConfig).reload_check_configs = conf_reload_set
     return events
    def test_get_host_address(self, mock_check_yaml, mock_get, *args):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP': '127.0.0.1',
                    'containerStatuses': [
                        {'containerID': 'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'}
                    ]
                }
            }]
        }

        # (inspect, tpl_var, expected_result)
        ip_address_inspects = [
            ({'NetworkSettings': {}}, 'host', None),
            ({'NetworkSettings': {'IPAddress': ''}}, 'host', None),

            ({'NetworkSettings': {'IPAddress': '127.0.0.1'}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Networks': {}}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host_bridge', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}}}},
             'host', '172.17.0.2'),

            ({'NetworkSettings': {'Networks': {}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {}}}, 'host_bridge', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host_bridge', None),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'}
                }}},
             'host_bridge', '172.17.0.2'),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}
                }}},
             'host_foo', '192.168.0.2')
        ]

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, tpl_var, expected_ip in ip_address_inspects:
            state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
            sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
            self.assertEquals(sd_backend._get_host_address(state, 'container id', tpl_var), expected_ip)
            clear_singletons(self.auto_conf_agentConfig)
Пример #10
0
    def test_get_host_address(self, mock_check_yaml, mock_get, *args):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP': '127.0.0.1',
                    'containerStatuses': [
                        {'containerID': 'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'}
                    ]
                }
            }]
        }

        # (inspect, tpl_var, expected_result)
        ip_address_inspects = [
            ({'NetworkSettings': {}}, 'host', None),
            ({'NetworkSettings': {'IPAddress': ''}}, 'host', None),

            ({'NetworkSettings': {'IPAddress': '127.0.0.1'}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Networks': {}}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host_bridge', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}}}},
             'host', '172.17.0.2'),

            ({'NetworkSettings': {'Networks': {}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {}}}, 'host_bridge', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host_bridge', None),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'}
                }}},
             'host_bridge', '172.17.0.2'),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}
                }}},
             'host_foo', '192.168.0.2')
        ]

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, tpl_var, expected_ip in ip_address_inspects:
            state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
            sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
            self.assertEquals(sd_backend._get_host_address(state, 'container id', tpl_var), expected_ip)
            clear_singletons(self.auto_conf_agentConfig)
Пример #11
0
    def __init__(self, name, init_config, agentConfig, instances=None):
        if instances is not None and len(instances) > 1:
            raise Exception('Kubernetes check only supports one configured instance.')

        AgentCheck.__init__(self, name, init_config, agentConfig, instances)

        inst = instances[0] if instances is not None else None
        self.kubeutil = KubeUtil(instance=inst)

        if not self.kubeutil.kubelet_api_url:
            raise Exception('Unable to reach kubelet. Try setting the host parameter.')

        if agentConfig.get('service_discovery') and \
           agentConfig.get('service_discovery_backend') == 'docker':
            self._sd_backend = get_sd_backend(agentConfig)
        else:
            self._sd_backend = None

        self.leader_candidate = inst.get(LEADER_CANDIDATE)
        if self.leader_candidate:
            self.kubeutil.refresh_leader()

        self.k8s_namespace_regexp = None
        if inst:
            regexp = inst.get('namespace_name_regexp', None)
            if regexp:
                try:
                    self.k8s_namespace_regexp = re.compile(regexp)
                except re.error as e:
                    self.log.warning('Invalid regexp for "namespace_name_regexp" in configuration (ignoring regexp): %s' % str(e))

            self.event_retriever = None
            self._configure_event_collection(inst)
Пример #12
0
 def test_get_container_pid(self, *args):
     for c_ins, _, var_tpl, _, _, expected_pid in self.container_inspects:
         state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         self.assertEquals(
             sd_backend._get_container_pid(state, 'container id', var_tpl),
             expected_pid)
         clear_singletons(self.auto_conf_agentConfig)
Пример #13
0
 def test_get_config_id(self, mock_get_auto_confd_path):
     """Test get_config_id"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, _, _, expected_ident, _ in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             self.assertEqual(
                 sd_backend.get_config_id(DockerUtil().image_name_extractor(c_ins), c_ins.get('Config', {}).get('Labels', {})),
                 expected_ident)
             clear_singletons(self.auto_conf_agentConfig)
Пример #14
0
 def test_get_port(self, *args):
     for c_ins, _, var_tpl, expected_ports, _, _ in self.container_inspects:
         state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         if isinstance(expected_ports, str):
             self.assertEquals(sd_backend._get_port(state, 'container id', var_tpl), expected_ports)
         else:
             self.assertRaises(expected_ports, sd_backend._get_port, state, 'c_id', var_tpl)
         clear_singletons(self.auto_conf_agentConfig)
Пример #15
0
 def test_get_port(self):
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, var_tpl, expected_ports, _ in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             if isinstance(expected_ports, str):
                 self.assertEquals(sd_backend._get_port(c_ins, var_tpl), expected_ports)
             else:
                 self.assertRaises(expected_ports, sd_backend._get_port, c_ins, var_tpl)
             clear_singletons(self.auto_conf_agentConfig)
Пример #16
0
 def test_get_config_id(self):
     """Test get_config_id"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, _, _, expected_ident in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             self.assertEqual(
                 sd_backend.get_config_id(c_ins.get('Image'), c_ins.get('Labels', {})),
                 expected_ident)
             clear_singletons(self.auto_conf_agentConfig)
 def test_get_config_id(self, mock_get_auto_confd_path):
     """Test get_config_id"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, _, _, expected_ident, _ in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             self.assertEqual(
                 sd_backend.get_config_id(DockerUtil().image_name_extractor(c_ins), c_ins.get('Config', {}).get('Labels', {})),
                 expected_ident)
             clear_singletons(self.auto_conf_agentConfig)
Пример #18
0
 def test_get_port(self):
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, var_tpl, expected_ports, _ in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             if isinstance(expected_ports, str):
                 self.assertEquals(sd_backend._get_port(c_ins, var_tpl), expected_ports)
             else:
                 self.assertRaises(expected_ports, sd_backend._get_port, c_ins, var_tpl)
             clear_singletons(self.auto_conf_agentConfig)
 def test_get_port(self, *args):
     for c_ins, _, var_tpl, expected_ports, _ in self.container_inspects:
         state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         if isinstance(expected_ports, str):
             self.assertEquals(sd_backend._get_port(state, 'container id', var_tpl), expected_ports)
         else:
             self.assertRaises(expected_ports, sd_backend._get_port, state, 'c_id', var_tpl)
         clear_singletons(self.auto_conf_agentConfig)
Пример #20
0
 def test_get_config_id(self):
     """Test get_config_id"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for c_ins, _, _, _, expected_ident in self.container_inspects:
             sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
             self.assertEqual(
                 sd_backend.get_config_id(c_ins.get('Image'), c_ins.get('Labels', {})),
                 expected_ident)
             clear_singletons(self.auto_conf_agentConfig)
Пример #21
0
def _service_disco_configs(agentConfig):
    """ Retrieve all the service disco configs and return their conf dicts
    """
    if agentConfig.get('service_discovery') and agentConfig.get('service_discovery_backend') in SD_BACKENDS:
        sd_backend = get_sd_backend(agentConfig=agentConfig)
        service_disco_configs = sd_backend.get_configs()
    else:
        service_disco_configs = {}

    return service_disco_configs
 def test_get_check_configs(self, *args):
     """Test get_check_config with mocked container inspect and config template"""
     c_id = self.docker_container_inspect.get('Id')
     for image in self.mock_templates.keys():
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         state = _SDDockerBackendConfigFetchState(_get_container_inspect)
         self.assertEquals(
             sd_backend._get_check_configs(state, c_id, image)[0],
             self.mock_templates[image][1])
         clear_singletons(self.auto_conf_agentConfig)
Пример #23
0
 def test_get_check_configs(self, *args):
     """Test get_check_config with mocked container inspect and config template"""
     c_id = self.docker_container_inspect.get('Id')
     for image in self.mock_templates.keys():
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         state = _SDDockerBackendConfigFetchState(_get_container_inspect)
         self.assertEquals(
             sd_backend._get_check_configs(state, c_id, image)[0],
             self.mock_templates[image][1])
         clear_singletons(self.auto_conf_agentConfig)
Пример #24
0
def _service_disco_configs(agentConfig):
    """ Retrieve all the service disco configs and return their conf dicts
    """
    if agentConfig.get('service_discovery') and agentConfig.get(
            'service_discovery_backend') in SD_BACKENDS:
        sd_backend = get_sd_backend(agentConfig=agentConfig)
        service_disco_configs = sd_backend.get_configs()
    else:
        service_disco_configs = {}

    return service_disco_configs
Пример #25
0
 def test_get_check_configs(self, mock_inspect_container, mock_get_conf_tpls):
     """Test get_check_config with mocked container inspect and config template"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         with mock.patch.object(SDDockerBackend, '_get_host_address', return_value='127.0.0.1'):
             with mock.patch.object(SDDockerBackend, '_get_port', return_value='1337'):
                 c_id = self.docker_container_inspect.get('Id')
                 for image in self.mock_templates.keys():
                     sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
                     self.assertEquals(
                         sd_backend._get_check_configs(c_id, image)[0],
                         self.mock_templates[image][1])
                     clear_singletons(self.auto_conf_agentConfig)
Пример #26
0
 def test_get_check_configs(self, mock_inspect_container, mock_get_conf_tpls):
     """Test get_check_config with mocked container inspect and config template"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         with mock.patch.object(SDDockerBackend, '_get_host_address', return_value='127.0.0.1'):
             with mock.patch.object(SDDockerBackend, '_get_port', return_value='1337'):
                 c_id = self.docker_container_inspect.get('Id')
                 for image in self.mock_templates.keys():
                     sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
                     self.assertEquals(
                         sd_backend._get_check_configs(c_id, image)[0],
                         self.mock_templates[image][1])
                     clear_singletons(self.auto_conf_agentConfig)
 def test_get_config_templates(self, *args):
     """Test _get_config_templates with mocked get_check_tpls"""
     for agentConfig in self.agentConfigs:
         sd_backend = get_sd_backend(agentConfig=agentConfig)
         # normal cases
         for image in self.mock_templates.keys():
             template = sd_backend._get_config_templates(image)
             expected_template = self.mock_templates.get(image)[0]
             self.assertEquals(template, expected_template)
         # error cases
         for image in self.bad_mock_templates.keys():
             self.assertEquals(sd_backend._get_config_templates(image), None)
         clear_singletons(agentConfig)
Пример #28
0
 def test_get_config_templates(self, *args):
     """Test _get_config_templates with mocked get_check_tpls"""
     for agentConfig in self.agentConfigs:
         sd_backend = get_sd_backend(agentConfig=agentConfig)
         # normal cases
         for image in self.mock_templates.keys():
             template = sd_backend._get_config_templates(image)
             expected_template = self.mock_templates.get(image)[0]
             self.assertEquals(template, expected_template)
         # error cases
         for image in self.bad_mock_templates.keys():
             self.assertEquals(sd_backend._get_config_templates(image), None)
         clear_singletons(agentConfig)
Пример #29
0
def _service_disco_configs(agentConfig):
    """ Retrieve all the service disco configs and return their conf dicts
    """
    if agentConfig.get('service_discovery') and agentConfig.get('service_discovery_backend') in SD_BACKENDS:
        try:
            log.info("Fetching service discovery check configurations.")
            sd_backend = get_sd_backend(agentConfig=agentConfig)
            service_disco_configs = sd_backend.get_configs()
        except Exception:
            log.exception("Loading service discovery configurations failed.")
    else:
        service_disco_configs = {}

    return service_disco_configs
Пример #30
0
def _service_disco_configs(agentConfig):
    """ Retrieve all the service disco configs and return their conf dicts
    """
    if agentConfig.get('service_discovery') and agentConfig.get('service_discovery_backend') in SD_BACKENDS:
        try:
            log.info("Fetching service discovery check configurations.")
            sd_backend = get_sd_backend(agentConfig=agentConfig)
            service_disco_configs = sd_backend.get_configs()
        except Exception:
            log.exception("Loading service discovery configurations failed.")
    else:
        service_disco_configs = {}

    return service_disco_configs
Пример #31
0
 def test_get_config_templates(self, mock_get_check_tpls):
     """Test _get_config_templates with mocked get_check_tpls"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         with mock.patch.object(EtcdStore, 'get_client', return_value=None):
             with mock.patch.object(ConsulStore, 'get_client', return_value=None):
                 for agentConfig in self.agentConfigs:
                     sd_backend = get_sd_backend(agentConfig=agentConfig)
                     # normal cases
                     for image in self.mock_templates.keys():
                         template = sd_backend._get_config_templates(image)
                         expected_template = self.mock_templates.get(image)[0]
                         self.assertEquals(template, expected_template)
                     # error cases
                     for image in self.bad_mock_templates.keys():
                         self.assertEquals(sd_backend._get_config_templates(image), None)
                     clear_singletons(agentConfig)
Пример #32
0
 def test_get_config_templates(self, mock_get_check_tpls):
     """Test _get_config_templates with mocked get_check_tpls"""
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         with mock.patch.object(EtcdStore, 'get_client', return_value=None):
             with mock.patch.object(ConsulStore, 'get_client', return_value=None):
                 for agentConfig in self.agentConfigs:
                     sd_backend = get_sd_backend(agentConfig=agentConfig)
                     # normal cases
                     for image in self.mock_templates.keys():
                         template = sd_backend._get_config_templates(image)
                         expected_template = self.mock_templates.get(image)[0]
                         self.assertEquals(template, expected_template)
                     # error cases
                     for image in self.bad_mock_templates.keys():
                         self.assertEquals(sd_backend._get_config_templates(image), None)
                     clear_singletons(agentConfig)
Пример #33
0
    def __init__(self, name, init_config, agentConfig, instances=None):
        if instances is not None and len(instances) > 1:
            raise Exception(
                'Kubernetes check only supports one configured instance.')

        AgentCheck.__init__(self, name, init_config, agentConfig, instances)

        inst = instances[0] if instances is not None else None
        self.kubeutil = KubeUtil(instance=inst)
        if not self.kubeutil.kubelet_api_url:
            raise Exception(
                'Unable to reach kubelet. Try setting the host parameter.')

        if agentConfig.get('service_discovery') and \
           agentConfig.get('service_discovery_backend') == 'docker':
            self._sd_backend = get_sd_backend(agentConfig)
        else:
            self._sd_backend = None

        self.k8s_namespace_regexp = None
        if inst:
            regexp = inst.get('namespace_name_regexp', None)
            if regexp:
                try:
                    self.k8s_namespace_regexp = re.compile(regexp)
                except re.error as e:
                    self.log.warning(
                        'Invalid regexp for "namespace_name_regexp" in configuration (ignoring regexp): %s'
                        % str(e))

            self._collect_events = _is_affirmative(
                inst.get('collect_events', DEFAULT_COLLECT_EVENTS))
            if self._collect_events:
                self.event_retriever = self.kubeutil.get_event_retriever()
            elif self.kubeutil.collect_service_tag:
                # Only fetch service and pod events for service mapping
                event_delay = inst.get('service_tag_update_freq',
                                       DEFAULT_SERVICE_EVENT_FREQ)
                self.event_retriever = self.kubeutil.get_event_retriever(
                    kinds=['Service', 'Pod'], delay=event_delay)
            else:
                self.event_retriever = None
        else:
            self._collect_events = None
            self.event_retriever = None
Пример #34
0
 def test_fill_tpl(self):
     """Test _fill_tpl with mock _get_ports"""
     valid_configs = [
         # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))
         (
             ({}, {'host': 'localhost'}, [], None),
             ({'host': 'localhost'}, {})
         ),
         (
             ({'NetworkSettings': {'IPAddress': '127.0.0.1'}},
              {'host': '%%host%%', 'port': 1337}, ['host'], ['foo', 'bar:baz']),
             ({'host': '%%host%%', 'port': 1337, 'tags': ['foo', 'bar:baz']}, {'host': '127.0.0.1'})
         ),
         (
             ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Ports': {'42/tcp': None, '22/tcp': None}}},
              {'host': '%%host%%', 'port': '%%port_1%%', 'tags': ['env:test']},
              ['host', 'port_1'], ['foo', 'bar:baz']),
             ({'host': '%%host%%', 'port': '%%port_1%%', 'tags': ['env:test', 'foo', 'bar:baz']},
              {'host': '127.0.0.1', 'port_1': '42'})
         )
     ]
     with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
         for ac in self.agentConfigs:
             sd_backend = get_sd_backend(agentConfig=ac)
             try:
                 for co in valid_configs:
                     inspect, tpl, variables, tags = co[0]
                     instance_tpl, var_values = sd_backend._fill_tpl(inspect, tpl, variables, tags)
                     for key in instance_tpl.keys():
                         if isinstance(instance_tpl[key], list):
                             self.assertEquals(len(instance_tpl[key]), len(co[1][0].get(key)))
                             for elem in instance_tpl[key]:
                                 self.assertTrue(elem in co[1][0].get(key))
                         else:
                             self.assertEquals(instance_tpl[key], co[1][0].get(key))
                     self.assertEquals(var_values, co[1][1])
                 clear_singletons(ac)
             except Exception:
                 clear_singletons(ac)
                 raise
Пример #35
0
    def __init__(self, name, init_config, agentConfig, instances=None):
        if instances is not None and len(instances) > 1:
            raise Exception('Kubernetes check only supports one configured instance.')

        AgentCheck.__init__(self, name, init_config, agentConfig, instances)

        inst = instances[0] if instances is not None else None
        self.kubeutil = KubeUtil(instance=inst)
        if not self.kubeutil.kubelet_api_url:
            raise Exception('Unable to reach kubelet. Try setting the host parameter.')

        if agentConfig.get('service_discovery') and \
           agentConfig.get('service_discovery_backend') == 'docker':
            self._sd_backend = get_sd_backend(agentConfig)
        else:
            self._sd_backend = None

        self.k8s_namespace_regexp = None
        if inst:
            regexp = inst.get('namespace_name_regexp', None)
            if regexp:
                try:
                    self.k8s_namespace_regexp = re.compile(regexp)
                except re.error as e:
                    self.log.warning('Invalid regexp for "namespace_name_regexp" in configuration (ignoring regexp): %s' % str(e))

            self._collect_events = _is_affirmative(inst.get('collect_events', DEFAULT_COLLECT_EVENTS))
            if self._collect_events:
                self.event_retriever = self.kubeutil.get_event_retriever()
            elif self.kubeutil.collect_service_tag:
                # Only fetch service and pod events for service mapping
                event_delay = inst.get('service_tag_update_freq', DEFAULT_SERVICE_EVENT_FREQ)
                self.event_retriever = self.kubeutil.get_event_retriever(kinds=['Service', 'Pod'],
                                                                         delay=event_delay)
            else:
                self.event_retriever = None
        else:
            self._collect_events = None
            self.event_retriever = None
Пример #36
0
    def test_get_host(self, mock_check_yaml, mock_get):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP': '127.0.0.1',
                    'containerStatuses': [
                        {'containerID': 'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'}
                    ]
                }
            }]
        }

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, expected_ip, _ in self.container_inspects:
            with mock.patch.object(AbstractConfigStore, '__init__', return_value=None):
                with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
                    with mock.patch('utils.kubeutil.get_conf_path', return_value=None):
                        sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
                        self.assertEqual(sd_backend._get_host(c_ins), expected_ip)
                        clear_singletons(self.auto_conf_agentConfig)
Пример #37
0
    osname = get_os()
    checks_paths = get_checks_paths(agentConfig, osname)
    # this can happen if check.d is not found
    if checks_paths is None:
        log.error('Check directory not found, exiting. The agent is likely misconfigured.')
        sys.exit(3)

    try:
        confd_path = get_confd_path(osname)
    except PathNotFound, e:
        log.error("No conf.d folder found at '%s' or in the directory where "
                  "the Agent is currently deployed.\n" % e.args[0])
        sys.exit(3)

    if agentConfig.get('service_discovery') and agentConfig.get('service_discovery_backend') in SD_BACKENDS:
        sd_backend = get_sd_backend(agentConfig=agentConfig)
        service_disco_configs = sd_backend.get_configs()
    else:
        service_disco_configs = {}

    # We don't support old style configs anymore
    # So we iterate over the files in the checks.d directory
    # If there is a matching configuration file in the conf.d directory
    # then we import the check
    for check in itertools.chain(*checks_paths):
        sd_init_config, sd_instances, skip_config_lookup = None, None, False
        check_name = os.path.basename(check).split('.')[0]
        check_config = None
        if check_name in initialized_checks or check_name in init_failed_checks:
            log.debug('Skipping check %s because it has already been loaded from another location', check)
            continue
Пример #38
0
 def test_fill_tpl(self):
     """Test _fill_tpl with mock _get_ports"""
     valid_configs = [
         # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))
         (({}, {
             'host': 'localhost'
         }, [], None), ({
             'host': 'localhost'
         }, {})),
         (({
             'NetworkSettings': {
                 'IPAddress': '127.0.0.1'
             }
         }, {
             'host': '%%host%%',
             'port': 1337
         }, ['host'], ['foo', 'bar:baz']), ({
             'host': '%%host%%',
             'port': 1337,
             'tags': ['foo', 'bar:baz']
         }, {
             'host': '127.0.0.1'
         })),
         (({
             'NetworkSettings': {
                 'IPAddress': '127.0.0.1',
                 'Ports': {
                     '42/tcp': None,
                     '22/tcp': None
                 }
             }
         }, {
             'host': '%%host%%',
             'port': '%%port_1%%',
             'tags': ['env:test']
         }, ['host', 'port_1'], ['foo', 'bar:baz']), ({
             'host':
             '%%host%%',
             'port':
             '%%port_1%%',
             'tags': ['env:test', 'foo', 'bar:baz']
         }, {
             'host': '127.0.0.1',
             'port_1': '42'
         }))
     ]
     with mock.patch('utils.dockerutil.DockerUtil.client',
                     return_value=None):
         for ac in self.agentConfigs:
             sd_backend = get_sd_backend(agentConfig=ac)
             try:
                 for co in valid_configs:
                     inspect, tpl, variables, tags = co[0]
                     instance_tpl, var_values = sd_backend._fill_tpl(
                         inspect, tpl, variables, tags)
                     for key in instance_tpl.keys():
                         if isinstance(instance_tpl[key], list):
                             self.assertEquals(len(instance_tpl[key]),
                                               len(co[1][0].get(key)))
                             for elem in instance_tpl[key]:
                                 self.assertTrue(elem in co[1][0].get(key))
                         else:
                             self.assertEquals(instance_tpl[key],
                                               co[1][0].get(key))
                     self.assertEquals(var_values, co[1][1])
                 clear_singletons(ac)
             except Exception:
                 clear_singletons(ac)
                 raise
Пример #39
0
    def test_get_host_address(self, mock_check_yaml, mock_get):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP': '127.0.0.1',
                    'containerStatuses': [
                        {'containerID': 'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'}
                    ]
                }
            }]
        }

        # (inspect, tpl_var, expected_result)
        ip_address_inspects = [
            ({'NetworkSettings': {}}, 'host', None),
            ({'NetworkSettings': {'IPAddress': ''}}, 'host', None),

            ({'NetworkSettings': {'IPAddress': '127.0.0.1'}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Networks': {}}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host_bridge', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}}}},
             'host', '127.0.0.1'),

            ({'NetworkSettings': {'Networks': {}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {}}}, 'host_bridge', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host_bridge', None),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'}
                }}},
             'host_bridge', '172.17.0.2'),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}
                }}},
             'host_foo', '192.168.0.2')
        ]

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, tpl_var, expected_ip in ip_address_inspects:
            with mock.patch.object(AbstractConfigStore, '__init__', return_value=None):
                with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
                    with mock.patch('utils.kubeutil.get_conf_path', return_value=None):
                        sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
                        self.assertEquals(sd_backend._get_host_address(c_ins, tpl_var), expected_ip)
                        clear_singletons(self.auto_conf_agentConfig)
Пример #40
0
    def run(self, config=None):
        """Main loop of the collector"""

        # Gracefully exit on sigterm.
        signal.signal(signal.SIGTERM, self._handle_sigterm)

        # A SIGUSR1 signals an exit with an autorestart
        signal.signal(signal.SIGUSR1, self._handle_sigusr1)

        # Handle Keyboard Interrupt
        signal.signal(signal.SIGINT, self._handle_sigterm)

        # A SIGHUP signals a configuration reload
        signal.signal(signal.SIGHUP, self._handle_sighup)

        # Save the agent start-up stats.
        CollectorStatus().persist()

        # Intialize the collector.
        if not config:
            config = get_config(parse_args=True)

        self._agentConfig = self._set_agent_config_hostname(config)
        hostname = get_hostname(self._agentConfig)
        systemStats = get_system_stats(proc_path=self._agentConfig.get(
            'procfs_path', '/proc').rstrip('/'))
        emitters = self._get_emitters()

        # Initialize service discovery
        if self._agentConfig.get('service_discovery'):
            self.sd_backend = get_sd_backend(self._agentConfig)

        # Load the checks.d checks
        self._checksd = load_check_directory(self._agentConfig, hostname)

        # Initialize the Collector
        self.collector = Collector(self._agentConfig, emitters, systemStats,
                                   hostname)

        # In developer mode, the number of runs to be included in a single collector profile
        self.collector_profile_interval = self._agentConfig.get(
            'collector_profile_interval', DEFAULT_COLLECTOR_PROFILE_INTERVAL)

        # Configure the watchdog.
        self.check_frequency = int(self._agentConfig['check_freq'])
        watchdog = self._get_watchdog(self.check_frequency)

        # Initialize the auto-restarter
        self.restart_interval = int(
            self._agentConfig.get('restart_interval', RESTART_INTERVAL))
        self.agent_start = time.time()

        profiled = False
        collector_profiled_runs = 0

        # Run the main loop.
        while self.run_forever:
            log.debug("Found {num_checks} checks".format(
                num_checks=len(self._checksd['initialized_checks'])))

            # Setup profiling if necessary
            if self.in_developer_mode and not profiled:
                try:
                    profiler = AgentProfiler()
                    profiler.enable_profiling()
                    profiled = True
                except Exception as e:
                    log.warn("Cannot enable profiler: %s" % str(e))

            # Do the work.
            self.collector.run(checksd=self._checksd,
                               start_event=self.start_event,
                               configs_reloaded=self.configs_reloaded)

            # This flag is used to know if the check configs have been reloaded at the current
            # run of the agent yet or not. It's used by the collector to know if it needs to
            # look for the AgentMetrics check and pop it out.
            # See: https://github.com/DataDog/dd-agent/blob/5.6.x/checks/collector.py#L265-L272
            self.configs_reloaded = False

            # Look for change in the config template store.
            # The self.sd_backend.reload_check_configs flag is set
            # to True if a config reload is needed.
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               not self.sd_backend.reload_check_configs:
                try:
                    self.sd_backend.reload_check_configs = get_config_store(
                        self._agentConfig).crawl_config_template()
                except Exception as e:
                    log.warn(
                        'Something went wrong while looking for config template changes: %s'
                        % str(e))

            # Check if we should run service discovery
            # The `reload_check_configs` flag can be set through the docker_daemon check or
            # using ConfigStore.crawl_config_template
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               self.sd_backend.reload_check_configs:
                self.reload_configs()
                self.configs_reloaded = True
                self.sd_backend.reload_check_configs = False

            if profiled:
                if collector_profiled_runs >= self.collector_profile_interval:
                    try:
                        profiler.disable_profiling()
                        profiled = False
                        collector_profiled_runs = 0
                    except Exception as e:
                        log.warn("Cannot disable profiler: %s" % str(e))

            # Check if we should restart.
            if self.autorestart and self._should_restart():
                self._do_restart()

            # Only plan for next loop if we will continue, otherwise exit quickly.
            if self.run_forever:
                if watchdog:
                    watchdog.reset()
                if profiled:
                    collector_profiled_runs += 1
                log.debug("Sleeping for {0} seconds".format(
                    self.check_frequency))
                time.sleep(self.check_frequency)

        # Now clean-up.
        try:
            CollectorStatus.remove_latest_status()
        except Exception:
            pass

        # Explicitly kill the process, because it might be running as a daemon.
        log.info("Exiting. Bye bye.")
        sys.exit(0)
 def test_get_container_pid(self, *args):
     for c_ins, _, var_tpl, _, _, expected_pid in self.container_inspects:
         state = _SDDockerBackendConfigFetchState(lambda _: c_ins)
         sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
         self.assertEquals(sd_backend._get_container_pid(state, 'container id', var_tpl), expected_pid)
         clear_singletons(self.auto_conf_agentConfig)
Пример #42
0
 def _get_events(self):
     """Get the list of events."""
     events, conf_reload_set = self.docker_util.get_events()
     if conf_reload_set and self._service_discovery:
         get_sd_backend(self.agentConfig).reload_check_configs = conf_reload_set
     return events
Пример #43
0
    def test_fill_tpl(self, *args):
        """Test _fill_tpl with mocked docker client"""

        valid_configs = [
            # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))
            (({}, {
                'host': 'localhost'
            }, [], None), ({
                'host': 'localhost'
            }, {})),
            (({
                'NetworkSettings': {
                    'IPAddress': ''
                }
            }, {
                'host': 'localhost'
            }, [], None), ({
                'host': 'localhost'
            }, {})),
            (({
                'NetworkSettings': {
                    'Networks': {}
                }
            }, {
                'host': 'localhost'
            }, [], None), ({
                'host': 'localhost'
            }, {})),
            (({
                'NetworkSettings': {
                    'Networks': {
                        'bridge': {}
                    }
                }
            }, {
                'host': 'localhost'
            }, [], None), ({
                'host': 'localhost'
            }, {})),
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '127.0.0.1'
                    }
                }, {
                    'host': '%%host%%',
                    'port': 1337
                }, ['host'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host': '127.0.0.1'
                }),
            ),
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '127.0.0.1',
                        'Networks': {}
                    }
                }, {
                    'host': '%%host%%',
                    'port': 1337
                }, ['host'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host': '127.0.0.1'
                }),
            ),
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '127.0.0.1',
                        'Networks': {
                            'bridge': {
                                'IPAddress': '172.17.0.2'
                            }
                        }
                    }
                }, {
                    'host': '%%host%%',
                    'port': 1337
                }, ['host'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host': '172.17.0.2'
                }),
            ),
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '',
                        'Networks': {
                            'bridge': {
                                'IPAddress': '172.17.0.2'
                            },
                            'foo': {
                                'IPAddress': '192.168.0.2'
                            }
                        }
                    }
                }, {
                    'host': '%%host_bridge%%',
                    'port': 1337
                }, ['host_bridge'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host_bridge%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host_bridge': '172.17.0.2'
                }),
            ),
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '',
                        'Networks': {
                            'bridge': {
                                'IPAddress': '172.17.0.2'
                            },
                            'foo': {
                                'IPAddress': '192.168.0.2'
                            }
                        }
                    }
                }, {
                    'host': '%%host_foo%%',
                    'port': 1337
                }, ['host_foo'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host_foo%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host_foo': '192.168.0.2'
                }),
            ),
            (({
                'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Ports': {
                        '42/tcp': None,
                        '22/tcp': None
                    }
                }
            }, {
                'host': '%%host%%',
                'port': '%%port_1%%',
                'tags': ['env:test']
            }, ['host', 'port_1'], ['foo', 'bar:baz']), ({
                'host':
                '%%host%%',
                'port':
                '%%port_1%%',
                'tags': ['env:test', 'foo', 'bar:baz']
            }, {
                'host': '127.0.0.1',
                'port_1': '42'
            }))
        ]

        # should not fail but return something specific
        edge_cases = [
            # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))

            # specify bridge but there is also a default IPAddress (networks should be preferred)
            (({
                'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Networks': {
                        'bridge': {
                            'IPAddress': '172.17.0.2'
                        }
                    }
                }
            }, {
                'host': '%%host_bridge%%',
                'port': 1337
            }, ['host_bridge'], ['foo', 'bar:baz']), ({
                'host':
                '%%host_bridge%%',
                'port':
                1337,
                'tags': ['foo', 'bar:baz']
            }, {
                'host_bridge':
                '172.17.0.2'
            })),
            # specify index but there is a default IPAddress (there's a specifier, even if it's wrong, walking networks should be preferred)
            (
                ({
                    'NetworkSettings': {
                        'IPAddress': '127.0.0.1',
                        'Networks': {
                            'bridge': {
                                'IPAddress': '172.17.0.2'
                            }
                        }
                    }
                }, {
                    'host': '%%host_0%%',
                    'port': 1337
                }, ['host_0'], ['foo', 'bar:baz']),
                ({
                    'host': '%%host_0%%',
                    'port': 1337,
                    'tags': ['foo', 'bar:baz']
                }, {
                    'host_0': '172.17.0.2'
                }),
            ),
            # missing key for host, bridge network should be preferred
            (
                ({
                    'NetworkSettings': {
                        'Networks': {
                            'bridge': {
                                'IPAddress': '127.0.0.1'
                            },
                            'foo': {
                                'IPAddress': '172.17.0.2'
                            }
                        }
                    }
                }, {
                    'host': '%%host_bar%%',
                    'port': 1337
                }, ['host_bar'], []),
                ({
                    'host': '%%host_bar%%',
                    'port': 1337
                }, {
                    'host_bar': '127.0.0.1'
                }),
            ),
            # missing index for port
            (({
                'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Ports': {
                        '42/tcp': None,
                        '22/tcp': None
                    }
                }
            }, {
                'host': '%%host%%',
                'port': '%%port_2%%',
                'tags': ['env:test']
            }, ['host', 'port_2'], ['foo', 'bar:baz']), ({
                'host':
                '%%host%%',
                'port':
                '%%port_2%%',
                'tags': ['env:test', 'foo', 'bar:baz']
            }, {
                'host': '127.0.0.1',
                'port_2': '42'
            }))
        ]

        # should raise
        invalid_config = [
            # ((inspect, instance_tpl, variables, tags), expected_exception)

            # template variable but no IPAddress available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': '%%host%%',
                    'port': 1337
                }, ['host'], ['foo', 'bar:baz']),
                Exception,
            ),
            # index but no IPAddress available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': '%%host_0%%',
                    'port': 1337
                }, ['host_0'], ['foo', 'bar:baz']),
                Exception,
            ),
            # key but no IPAddress available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': '%%host_foo%%',
                    'port': 1337
                }, ['host_foo'], ['foo', 'bar:baz']),
                Exception,
            ),

            # template variable but no port available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': 'localhost',
                    'port': '%%port%%'
                }, ['port'], []),
                Exception,
            ),
            # index but no port available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': 'localhost',
                    'port_0': '%%port%%'
                }, ['port_0'], []),
                Exception,
            ),
            # key but no port available
            (
                ({
                    'NetworkSettings': {
                        'Networks': {}
                    }
                }, {
                    'host': 'localhost',
                    'port': '%%port_foo%%'
                }, ['port_foo'], []),
                Exception,
            )
        ]

        for ac in self.agentConfigs:
            sd_backend = get_sd_backend(agentConfig=ac)
            try:
                for co in valid_configs + edge_cases:
                    inspect, tpl, variables, tags = co[0]
                    state = _SDDockerBackendConfigFetchState(lambda _: inspect)
                    instance_tpl, var_values = sd_backend._fill_tpl(
                        state, 'c_id', tpl, variables, tags)
                    for key in instance_tpl.keys():
                        if isinstance(instance_tpl[key], list):
                            self.assertEquals(len(instance_tpl[key]),
                                              len(co[1][0].get(key)))
                            for elem in instance_tpl[key]:
                                self.assertTrue(elem in co[1][0].get(key))
                        else:
                            self.assertEquals(instance_tpl[key],
                                              co[1][0].get(key))
                    self.assertEquals(var_values, co[1][1])

                for co in invalid_config:
                    inspect, tpl, variables, tags = co[0]
                    state = _SDDockerBackendConfigFetchState(lambda _: inspect)
                    self.assertRaises(
                        co[1],
                        sd_backend._fill_tpl(state, 'c_id', tpl, variables,
                                             tags))
            finally:
                clear_singletons(ac)
Пример #44
0
    def run(self, config=None):
        """Main loop of the collector"""

        # Gracefully exit on sigterm.
        signal.signal(signal.SIGTERM, self._handle_sigterm)

        # A SIGUSR1 signals an exit with an autorestart
        signal.signal(signal.SIGUSR1, self._handle_sigusr1)

        # Handle Keyboard Interrupt
        signal.signal(signal.SIGINT, self._handle_sigterm)

        # A SIGHUP signals a configuration reload
        signal.signal(signal.SIGHUP, self._handle_sighup)

        # Save the agent start-up stats.
        CollectorStatus().persist()

        # Intialize the collector.
        if not config:
            config = get_config(parse_args=True)

        self._agentConfig = self._set_agent_config_hostname(config)
        hostname = get_hostname(self._agentConfig)
        systemStats = get_system_stats(
            proc_path=self._agentConfig.get('procfs_path', '/proc').rstrip('/')
        )
        emitters = self._get_emitters()

        # Initialize service discovery
        if self._agentConfig.get('service_discovery'):
            self.sd_backend = get_sd_backend(self._agentConfig)

        if _is_affirmative(self._agentConfig.get('sd_jmx_enable')):
            pipe_path = get_jmx_pipe_path()
            if Platform.is_windows():
                pipe_name = pipe_path.format(pipename=SD_PIPE_NAME)
            else:
                pipe_name = os.path.join(pipe_path, SD_PIPE_NAME)

            if os.access(pipe_path, os.W_OK):
                if not os.path.exists(pipe_name):
                    os.mkfifo(pipe_name)
                self.sd_pipe = os.open(pipe_name, os.O_RDWR) # RW to avoid blocking (will only W)

                # Initialize Supervisor proxy
                self.supervisor_proxy = self._get_supervisor_socket(self._agentConfig)
            else:
                log.debug('Unable to create pipe in temporary directory. JMX service discovery disabled.')

        # Load the checks.d checks
        self._checksd = load_check_directory(self._agentConfig, hostname)

        # Load JMX configs if available
        if self._jmx_service_discovery_enabled:
            jmx_sd_configs = generate_jmx_configs(self._agentConfig, hostname)
            if jmx_sd_configs:
                self._submit_jmx_service_discovery(jmx_sd_configs)

        # Initialize the Collector
        self.collector = Collector(self._agentConfig, emitters, systemStats, hostname)

        # In developer mode, the number of runs to be included in a single collector profile
        try:
            self.collector_profile_interval = int(
                self._agentConfig.get('collector_profile_interval', DEFAULT_COLLECTOR_PROFILE_INTERVAL))
        except ValueError:
            log.warn('collector_profile_interval is invalid. '
                     'Using default value instead (%s).' % DEFAULT_COLLECTOR_PROFILE_INTERVAL)
            self.collector_profile_interval = DEFAULT_COLLECTOR_PROFILE_INTERVAL

        # Configure the watchdog.
        self.check_frequency = int(self._agentConfig['check_freq'])
        watchdog = self._get_watchdog(self.check_frequency)

        # Initialize the auto-restarter
        self.restart_interval = int(self._agentConfig.get('restart_interval', RESTART_INTERVAL))
        self.agent_start = time.time()

        self.allow_profiling = self._agentConfig.get('allow_profiling', True)

        profiled = False
        collector_profiled_runs = 0

        # Run the main loop.
        while self.run_forever:
            # Setup profiling if necessary
            if self.allow_profiling and self.in_developer_mode and not profiled:
                try:
                    profiler = AgentProfiler()
                    profiler.enable_profiling()
                    profiled = True
                except Exception as e:
                    log.warn("Cannot enable profiler: %s" % str(e))

            if self.reload_configs_flag:
                if isinstance(self.reload_configs_flag, set):
                    self.reload_configs(checks_to_reload=self.reload_configs_flag)
                else:
                    self.reload_configs()

            # Do the work. Pass `configs_reloaded` to let the collector know if it needs to
            # look for the AgentMetrics check and pop it out.
            self.collector.run(checksd=self._checksd,
                               start_event=self.start_event,
                               configs_reloaded=True if self.reload_configs_flag else False)

            self.reload_configs_flag = False

            # Look for change in the config template store.
            # The self.sd_backend.reload_check_configs flag is set
            # to True if a config reload is needed.
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               not self.sd_backend.reload_check_configs:
                try:
                    self.sd_backend.reload_check_configs = get_config_store(
                        self._agentConfig).crawl_config_template()
                except Exception as e:
                    log.warn('Something went wrong while looking for config template changes: %s' % str(e))

            # Check if we should run service discovery
            # The `reload_check_configs` flag can be set through the docker_daemon check or
            # using ConfigStore.crawl_config_template
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               self.sd_backend.reload_check_configs:
                self.reload_configs_flag = self.sd_backend.reload_check_configs
                self.sd_backend.reload_check_configs = False

            if profiled:
                if collector_profiled_runs >= self.collector_profile_interval:
                    try:
                        profiler.disable_profiling()
                        profiled = False
                        collector_profiled_runs = 0
                    except Exception as e:
                        log.warn("Cannot disable profiler: %s" % str(e))

            # Check if we should restart.
            if self.autorestart and self._should_restart():
                self._do_restart()

            # Only plan for next loop if we will continue, otherwise exit quickly.
            if self.run_forever:
                if watchdog:
                    watchdog.reset()
                if profiled:
                    collector_profiled_runs += 1
                log.debug("Sleeping for {0} seconds".format(self.check_frequency))
                time.sleep(self.check_frequency)

        # Now clean-up.
        try:
            CollectorStatus.remove_latest_status()
        except Exception:
            pass

        # Explicitly kill the process, because it might be running as a daemon.
        log.info("Exiting. Bye bye.")
        sys.exit(0)
Пример #45
0
def clear_singletons(agentConfig):
    get_config_store(agentConfig)._drop()
    get_sd_backend(agentConfig)._drop()
Пример #46
0
    if checks_paths is None:
        log.error(
            'Check directory not found, exiting. The agent is likely misconfigured.'
        )
        sys.exit(3)

    try:
        confd_path = get_confd_path(osname)
    except PathNotFound, e:
        log.error("No conf.d folder found at '%s' or in the directory where "
                  "the Agent is currently deployed.\n" % e.args[0])
        sys.exit(3)

    if agentConfig.get('service_discovery') and agentConfig.get(
            'service_discovery_backend') in SD_BACKENDS:
        sd_backend = get_sd_backend(agentConfig=agentConfig)
        service_disco_configs = sd_backend.get_configs()
    else:
        service_disco_configs = {}

    # We don't support old style configs anymore
    # So we iterate over the files in the checks.d directory
    # If there is a matching configuration file in the conf.d directory
    # then we import the check
    for check in itertools.chain(*checks_paths):
        sd_init_config, sd_instances, skip_config_lookup = None, None, False
        check_name = os.path.basename(check).split('.')[0]
        check_config = None
        if check_name in initialized_checks or check_name in init_failed_checks:
            log.debug(
                'Skipping check %s because it has already been loaded from another location',
Пример #47
0
 def _get_events(self):
     """Get the list of events."""
     events, should_reload_conf = self.docker_util.get_events()
     if should_reload_conf and self._service_discovery:
         get_sd_backend(self.agentConfig).reload_check_configs = True
     return events
Пример #48
0
 def _get_events(self):
     """Get the list of events."""
     events, changed_container_ids = self.docker_util.get_events()
     if changed_container_ids and self._service_discovery:
         get_sd_backend(self.agentConfig).update_checks(changed_container_ids)
     return events
Пример #49
0
 def _get_events(self):
     """Get the list of events."""
     events, should_reload_conf = self.docker_util.get_events()
     if should_reload_conf and self._service_discovery:
         get_sd_backend(self.agentConfig).reload_check_configs = True
     return events
Пример #50
0
    def test_fill_tpl(self):
        """Test _fill_tpl with mocked docker client"""

        valid_configs = [
            # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))
            (({}, {'host': 'localhost'}, [], None), ({'host': 'localhost'}, {})),
            (
                ({'NetworkSettings': {'IPAddress': ''}}, {'host': 'localhost'}, [], None),
                ({'host': 'localhost'}, {})
            ),
            (
                ({'NetworkSettings': {'Networks': {}}}, {'host': 'localhost'}, [], None),
                ({'host': 'localhost'}, {})
            ),
            (
                ({'NetworkSettings': {'Networks': {'bridge': {}}}}, {'host': 'localhost'}, [], None),
                ({'host': 'localhost'}, {})
            ),
            (
                ({'NetworkSettings': {'IPAddress': '127.0.0.1'}},
                 {'host': '%%host%%', 'port': 1337}, ['host'], ['foo', 'bar:baz']),
                ({'host': '%%host%%', 'port': 1337, 'tags': ['foo', 'bar:baz']}, {'host': '127.0.0.1'}),
            ),
            (
                ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Networks': {}}},
                 {'host': '%%host%%', 'port': 1337}, ['host'], ['foo', 'bar:baz']),
                ({'host': '%%host%%', 'port': 1337, 'tags': ['foo', 'bar:baz']}, {'host': '127.0.0.1'}),
            ),
            (
                ({'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Networks': {'bridge': {'IPAddress': '172.17.0.2'}}}
                  },
                 {'host': '%%host%%', 'port': 1337}, ['host'], ['foo', 'bar:baz']),
                ({'host': '%%host%%', 'port': 1337, 'tags': ['foo', 'bar:baz']}, {'host': '127.0.0.1'}),
            ),
            (
                ({'NetworkSettings': {
                    'IPAddress': '',
                    'Networks': {
                        'bridge': {'IPAddress': '172.17.0.2'},
                        'foo': {'IPAddress': '192.168.0.2'}
                    }}
                  },
                 {'host': '%%host_bridge%%', 'port': 1337}, ['host_bridge'], ['foo', 'bar:baz']),
                ({'host': '%%host_bridge%%', 'port': 1337, 'tags': ['foo', 'bar:baz']},
                 {'host_bridge': '172.17.0.2'}),
            ),
            (
                ({'NetworkSettings': {
                    'IPAddress': '',
                    'Networks': {
                        'bridge': {'IPAddress': '172.17.0.2'},
                        'foo': {'IPAddress': '192.168.0.2'}
                    }}
                  },
                 {'host': '%%host_foo%%', 'port': 1337}, ['host_foo'], ['foo', 'bar:baz']),
                ({'host': '%%host_foo%%', 'port': 1337, 'tags': ['foo', 'bar:baz']},
                 {'host_foo': '192.168.0.2'}),
            ),
            (
                ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Ports': {'42/tcp': None, '22/tcp': None}}},
                 {'host': '%%host%%', 'port': '%%port_1%%', 'tags': ['env:test']},
                 ['host', 'port_1'], ['foo', 'bar:baz']),
                ({'host': '%%host%%', 'port': '%%port_1%%', 'tags': ['env:test', 'foo', 'bar:baz']},
                 {'host': '127.0.0.1', 'port_1': '42'})
            )
        ]

        # should not fail but return something specific
        edge_cases = [
            # ((inspect, instance_tpl, variables, tags), (expected_instance_tpl, expected_var_values))

            # specify bridge but there is also a default IPAddress (networks should be preferred)
            (
                ({'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Networks': {'bridge': {'IPAddress': '172.17.0.2'}}}},
                 {'host': '%%host_bridge%%', 'port': 1337}, ['host_bridge'], ['foo', 'bar:baz']),
                ({'host': '%%host_bridge%%', 'port': 1337, 'tags': ['foo', 'bar:baz']},
                 {'host_bridge': '172.17.0.2'})
            ),
            # specify index but there is a default IPAddress (there's a specifier, even if it's wrong, walking networks should be preferred)
            (
                ({'NetworkSettings': {
                    'IPAddress': '127.0.0.1',
                    'Networks': {'bridge': {'IPAddress': '172.17.0.2'}}}},
                 {'host': '%%host_0%%', 'port': 1337}, ['host_0'], ['foo', 'bar:baz']),
                ({'host': '%%host_0%%', 'port': 1337, 'tags': ['foo', 'bar:baz']}, {'host_0': '172.17.0.2'}),
            ),
            # missing key for host, bridge network should be preferred
            (
                ({'NetworkSettings': {'Networks': {
                    'bridge': {'IPAddress': '127.0.0.1'},
                    'foo': {'IPAddress': '172.17.0.2'}}}},
                 {'host': '%%host_bar%%', 'port': 1337}, ['host_bar'], []),
                ({'host': '%%host_bar%%', 'port': 1337}, {'host_bar': '127.0.0.1'}),
            ),
            # missing index for port
            (
                ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Ports': {'42/tcp': None, '22/tcp': None}}},
                 {'host': '%%host%%', 'port': '%%port_2%%', 'tags': ['env:test']},
                 ['host', 'port_2'], ['foo', 'bar:baz']),
                ({'host': '%%host%%', 'port': '%%port_2%%', 'tags': ['env:test', 'foo', 'bar:baz']},
                 {'host': '127.0.0.1', 'port_2': '42'})
            )
        ]

        # should raise
        invalid_config = [
            # ((inspect, instance_tpl, variables, tags), expected_exception)

            # template variable but no IPAddress available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': '%%host%%', 'port': 1337}, ['host'], ['foo', 'bar:baz']),
                Exception,
            ),
            # index but no IPAddress available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': '%%host_0%%', 'port': 1337}, ['host_0'], ['foo', 'bar:baz']),
                Exception,
            ),
            # key but no IPAddress available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': '%%host_foo%%', 'port': 1337}, ['host_foo'], ['foo', 'bar:baz']),
                Exception,
            ),

            # template variable but no port available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': 'localhost', 'port': '%%port%%'}, ['port'], []),
                Exception,
            ),
            # index but no port available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': 'localhost', 'port_0': '%%port%%'}, ['port_0'], []),
                Exception,
            ),
            # key but no port available
            (
                ({'NetworkSettings': {'Networks': {}}},
                 {'host': 'localhost', 'port': '%%port_foo%%'}, ['port_foo'], []),
                Exception,
            )
        ]

        with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
            with mock.patch.object(EtcdStore, 'get_client', return_value=None):
                with mock.patch.object(ConsulStore, 'get_client', return_value=None):
                    for ac in self.agentConfigs:
                        sd_backend = get_sd_backend(agentConfig=ac)
                        try:
                            for co in valid_configs + edge_cases:
                                inspect, tpl, variables, tags = co[0]
                                instance_tpl, var_values = sd_backend._fill_tpl(inspect, tpl, variables, tags)
                                for key in instance_tpl.keys():
                                    if isinstance(instance_tpl[key], list):
                                        self.assertEquals(len(instance_tpl[key]), len(co[1][0].get(key)))
                                        for elem in instance_tpl[key]:
                                            self.assertTrue(elem in co[1][0].get(key))
                                    else:
                                        self.assertEquals(instance_tpl[key], co[1][0].get(key))
                                self.assertEquals(var_values, co[1][1])

                            for co in invalid_config:
                                inspect, tpl, variables, tags = co[0]
                                self.assertRaises(co[1], sd_backend._fill_tpl(inspect, tpl, variables, tags))

                            clear_singletons(ac)
                        except Exception:
                            clear_singletons(ac)
                            raise
Пример #51
0
    def run(self, config=None):
        """Main loop of the collector"""

        # Gracefully exit on sigterm.
        signal.signal(signal.SIGTERM, self._handle_sigterm)

        # A SIGUSR1 signals an exit with an autorestart
        signal.signal(signal.SIGUSR1, self._handle_sigusr1)

        # Handle Keyboard Interrupt
        signal.signal(signal.SIGINT, self._handle_sigterm)

        # A SIGHUP signals a configuration reload
        signal.signal(signal.SIGHUP, self._handle_sighup)

        # Save the agent start-up stats.
        CollectorStatus().persist()

        # Intialize the collector.
        if not config:
            config = get_config(parse_args=True)

        self._agentConfig = self._set_agent_config_hostname(config)
        hostname = get_hostname(self._agentConfig)
        systemStats = get_system_stats()
        emitters = self._get_emitters()

        # Initialize service discovery
        if self._agentConfig.get("service_discovery"):
            self.sd_backend = get_sd_backend(self._agentConfig)

        # Load the checks.d checks
        self._checksd = load_check_directory(self._agentConfig, hostname)

        # Initialize the Collector
        self.collector = Collector(self._agentConfig, emitters, systemStats, hostname)

        # In developer mode, the number of runs to be included in a single collector profile
        self.collector_profile_interval = self._agentConfig.get(
            "collector_profile_interval", DEFAULT_COLLECTOR_PROFILE_INTERVAL
        )

        # Configure the watchdog.
        self.check_frequency = int(self._agentConfig["check_freq"])
        watchdog = self._get_watchdog(self.check_frequency)

        # Initialize the auto-restarter
        self.restart_interval = int(self._agentConfig.get("restart_interval", RESTART_INTERVAL))
        self.agent_start = time.time()

        profiled = False
        collector_profiled_runs = 0

        # Run the main loop.
        while self.run_forever:
            log.debug("Found {num_checks} checks".format(num_checks=len(self._checksd["initialized_checks"])))

            # Setup profiling if necessary
            if self.in_developer_mode and not profiled:
                try:
                    profiler = AgentProfiler()
                    profiler.enable_profiling()
                    profiled = True
                except Exception as e:
                    log.warn("Cannot enable profiler: %s" % str(e))

            # Do the work.
            self.collector.run(
                checksd=self._checksd, start_event=self.start_event, configs_reloaded=self.configs_reloaded
            )

            # This flag is used to know if the check configs have been reloaded at the current
            # run of the agent yet or not. It's used by the collector to know if it needs to
            # look for the AgentMetrics check and pop it out.
            # See: https://github.com/DataDog/dd-agent/blob/5.6.x/checks/collector.py#L265-L272
            self.configs_reloaded = False

            # Look for change in the config template store.
            # The self.sd_backend.reload_check_configs flag is set
            # to True if a config reload is needed.
            if (
                self._agentConfig.get("service_discovery")
                and self.sd_backend
                and not self.sd_backend.reload_check_configs
            ):
                try:
                    self.sd_backend.reload_check_configs = get_config_store(self._agentConfig).crawl_config_template()
                except Exception as e:
                    log.warn("Something went wrong while looking for config template changes: %s" % str(e))

            # Check if we should run service discovery
            # The `reload_check_configs` flag can be set through the docker_daemon check or
            # using ConfigStore.crawl_config_template
            if self._agentConfig.get("service_discovery") and self.sd_backend and self.sd_backend.reload_check_configs:
                self.reload_configs()
                self.configs_reloaded = True
                self.sd_backend.reload_check_configs = False

            if profiled:
                if collector_profiled_runs >= self.collector_profile_interval:
                    try:
                        profiler.disable_profiling()
                        profiled = False
                        collector_profiled_runs = 0
                    except Exception as e:
                        log.warn("Cannot disable profiler: %s" % str(e))

            # Check if we should restart.
            if self.autorestart and self._should_restart():
                self._do_restart()

            # Only plan for next loop if we will continue, otherwise exit quickly.
            if self.run_forever:
                if watchdog:
                    watchdog.reset()
                if profiled:
                    collector_profiled_runs += 1
                log.debug("Sleeping for {0} seconds".format(self.check_frequency))
                time.sleep(self.check_frequency)

        # Now clean-up.
        try:
            CollectorStatus.remove_latest_status()
        except Exception:
            pass

        # Explicitly kill the process, because it might be running as a daemon.
        log.info("Exiting. Bye bye.")
        sys.exit(0)
 def test_get_image_ident(self, *args):
     sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
     # normal cases
     for image, ident in self.image_formats.iteritems():
         self.assertEquals(ident, sd_backend.config_store._get_image_ident(image))
Пример #53
0
def clear_singletons(agentConfig):
    get_config_store(agentConfig)._drop()
    get_sd_backend(agentConfig)._drop()
Пример #54
0
    def run(self, config=None):
        """Main loop of the collector"""

        # Gracefully exit on sigterm.
        signal.signal(signal.SIGTERM, self._handle_sigterm)

        if not Platform.is_windows():
            # A SIGUSR1 signals an exit with an autorestart
            signal.signal(signal.SIGUSR1, self._handle_sigusr1)

            # Handle Keyboard Interrupt
            signal.signal(signal.SIGINT, self._handle_sigterm)

            # A SIGHUP signals a configuration reload
            signal.signal(signal.SIGHUP, self._handle_sighup)

        # Save the agent start-up stats.
        CollectorStatus().persist()

        # Intialize the collector.
        if not config:
            config = get_config(parse_args=True)

        self._agentConfig = self._set_agent_config_hostname(config)
        hostname = get_hostname(self._agentConfig)
        systemStats = get_system_stats(proc_path=self._agentConfig.get(
            'procfs_path', '/proc').rstrip('/'))
        emitters = self._get_emitters()

        # Initialize service discovery
        if self._agentConfig.get('service_discovery'):
            self.sd_backend = get_sd_backend(self._agentConfig)

        if _is_affirmative(self._agentConfig.get('sd_jmx_enable', False)):
            pipe_path = get_jmx_pipe_path()
            if Platform.is_windows():
                pipe_name = pipe_path.format(pipename=SD_PIPE_NAME)
            else:
                pipe_name = os.path.join(pipe_path, SD_PIPE_NAME)

            if os.access(pipe_path, os.W_OK):
                if not os.path.exists(pipe_name):
                    os.mkfifo(pipe_name)
                self.sd_pipe = os.open(
                    pipe_name, os.O_RDWR)  # RW to avoid blocking (will only W)

                # Initialize Supervisor proxy
                self.supervisor_proxy = self._get_supervisor_socket(
                    self._agentConfig)
            else:
                log.debug(
                    'Unable to create pipe in temporary directory. JMX service discovery disabled.'
                )

        # Load the checks.d checks
        self._checksd = load_check_directory(self._agentConfig, hostname)

        # Load JMX configs if available
        if self._jmx_service_discovery_enabled:
            jmx_sd_configs = generate_jmx_configs(self._agentConfig, hostname)
            if jmx_sd_configs:
                self._submit_jmx_service_discovery(jmx_sd_configs)

        # Initialize the Collector
        self.collector = Collector(self._agentConfig, emitters, systemStats,
                                   hostname)

        # In developer mode, the number of runs to be included in a single collector profile
        try:
            self.collector_profile_interval = int(
                self._agentConfig.get('collector_profile_interval',
                                      DEFAULT_COLLECTOR_PROFILE_INTERVAL))
        except ValueError:
            log.warn('collector_profile_interval is invalid. '
                     'Using default value instead (%s).' %
                     DEFAULT_COLLECTOR_PROFILE_INTERVAL)
            self.collector_profile_interval = DEFAULT_COLLECTOR_PROFILE_INTERVAL

        # Configure the watchdog.
        self.check_frequency = int(self._agentConfig['check_freq'])
        watchdog = self._get_watchdog(self.check_frequency)

        # Initialize the auto-restarter
        self.restart_interval = int(
            self._agentConfig.get('restart_interval', RESTART_INTERVAL))
        self.agent_start = time.time()

        self.allow_profiling = self._agentConfig.get('allow_profiling', True)

        profiled = False
        collector_profiled_runs = 0

        # Run the main loop.
        while self.run_forever:
            # Setup profiling if necessary
            if self.allow_profiling and self.in_developer_mode and not profiled:
                try:
                    profiler = AgentProfiler()
                    profiler.enable_profiling()
                    profiled = True
                except Exception as e:
                    log.warn("Cannot enable profiler: %s" % str(e))

            if self.reload_configs_flag:
                if isinstance(self.reload_configs_flag, set):
                    self.reload_configs(
                        checks_to_reload=self.reload_configs_flag)
                else:
                    self.reload_configs()

            # Do the work. Pass `configs_reloaded` to let the collector know if it needs to
            # look for the AgentMetrics check and pop it out.
            self.collector.run(
                checksd=self._checksd,
                start_event=self.start_event,
                configs_reloaded=True if self.reload_configs_flag else False)

            self.reload_configs_flag = False

            # Look for change in the config template store.
            # The self.sd_backend.reload_check_configs flag is set
            # to True if a config reload is needed.
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               not self.sd_backend.reload_check_configs:
                try:
                    self.sd_backend.reload_check_configs = get_config_store(
                        self._agentConfig).crawl_config_template()
                except Exception as e:
                    log.warn(
                        'Something went wrong while looking for config template changes: %s'
                        % str(e))

            # Check if we should run service discovery
            # The `reload_check_configs` flag can be set through the docker_daemon check or
            # using ConfigStore.crawl_config_template
            if self._agentConfig.get('service_discovery') and self.sd_backend and \
               self.sd_backend.reload_check_configs:
                self.reload_configs_flag = self.sd_backend.reload_check_configs
                self.sd_backend.reload_check_configs = False

            if profiled:
                if collector_profiled_runs >= self.collector_profile_interval:
                    try:
                        profiler.disable_profiling()
                        profiled = False
                        collector_profiled_runs = 0
                    except Exception as e:
                        log.warn("Cannot disable profiler: %s" % str(e))

            # Check if we should restart.
            if self.autorestart and self._should_restart():
                self._do_restart()

            # Only plan for next loop if we will continue, otherwise exit quickly.
            if self.run_forever:
                if watchdog:
                    watchdog.reset()
                if profiled:
                    collector_profiled_runs += 1
                log.debug("Sleeping for {0} seconds".format(
                    self.check_frequency))
                time.sleep(self.check_frequency)

        # Now clean-up.
        try:
            CollectorStatus.remove_latest_status()
        except Exception:
            pass

        # Explicitly kill the process, because it might be running as a daemon.
        log.info("Exiting. Bye bye.")
        sys.exit(0)
Пример #55
0
    def test_get_host_address(self, mock_check_yaml, mock_get):
        kubernetes_config = {'instances': [{'kubelet_port': 1337}]}
        pod_list = {
            'items': [{
                'status': {
                    'podIP': '127.0.0.1',
                    'containerStatuses': [
                        {'containerID': 'docker://389dc8a4361f3d6c866e9e9a7b6972b26a31c589c4e2f097375d55656a070bc9'}
                    ]
                }
            }]
        }

        # (inspect, tpl_var, expected_result)
        ip_address_inspects = [
            ({'NetworkSettings': {}}, 'host', None),
            ({'NetworkSettings': {'IPAddress': ''}}, 'host', None),

            ({'NetworkSettings': {'IPAddress': '127.0.0.1'}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {'IPAddress': '127.0.0.1', 'Networks': {}}}, 'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '',
                'Networks': {'bridge': {'IPAddress': '127.0.0.1'}}}},
             'host_bridge', '127.0.0.1'),
            ({'NetworkSettings': {
                'IPAddress': '127.0.0.1',
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}}}},
             'host', '172.17.0.2'),

            ({'NetworkSettings': {'Networks': {}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {}}}, 'host_bridge', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host', None),
            ({'NetworkSettings': {'Networks': {'bridge': {}}}}, 'host_bridge', None),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'}
                }}},
             'host_bridge', '172.17.0.2'),
            ({'NetworkSettings': {
                'Networks': {
                    'bridge': {'IPAddress': '172.17.0.2'},
                    'foo': {'IPAddress': '192.168.0.2'}
                }}},
             'host_foo', '192.168.0.2')
        ]

        mock_check_yaml.return_value = kubernetes_config
        mock_get.return_value = Response(pod_list)

        for c_ins, tpl_var, expected_ip in ip_address_inspects:
            with mock.patch.object(AbstractConfigStore, '__init__', return_value=None):
                with mock.patch('utils.dockerutil.DockerUtil.client', return_value=None):
                    with mock.patch('utils.kubeutil.get_conf_path', return_value=None):
                        sd_backend = get_sd_backend(agentConfig=self.auto_conf_agentConfig)
                        self.assertEquals(sd_backend._get_host_address(c_ins, tpl_var), expected_ip)
                        clear_singletons(self.auto_conf_agentConfig)