diff --git a/tests/core/test_service_discovery.py b/tests/core/test_service_discovery.py index aa61369b64..dfed2c16b3 100644 --- a/tests/core/test_service_discovery.py +++ b/tests/core/test_service_discovery.py @@ -174,6 +174,26 @@ class TestServiceDiscovery(unittest.TestCase): ])), } + image_formats = { + # Don't crash on empty string or None + '': '', + None: '', + # Shortest possibility + 'alpine': 'alpine', + # Historical docker format + 'nginx:latest': 'nginx', + # Org prefix to be removed + 'datadog/docker-dd-agent:latest-jmx': 'docker-dd-agent', + # Sha-pinning used by many orchestrators + 'redis@sha256:5bef08742407efd622d243692b79ba0055383bbce12900324f75e56f589aedb0': 'redis', + # Quirky pinning used by swarm + 'org/redis:latest@sha256:5bef08742407efd622d243692b79ba0055383bbce12900324f75e56f589aedb0': 'redis', + # Custom registry, simple form + 'myregistry.local:5000/testing/test-image:version': 'test-image', + # Custom registry, most insane form possible + 'myregistry.local:5000/testing/test-image:version@sha256:5bef08742407efd622d243692b79ba0055383bbce12900324f75e56f589aedb0': 'test-image', + } + def setUp(self): self.etcd_agentConfig = { 'service_discovery': True, @@ -328,6 +348,16 @@ def test_get_config_templates(self, *args): self.assertEquals(sd_backend._get_config_templates(image), None) clear_singletons(agentConfig) + @mock.patch('config.get_auto_confd_path', return_value=os.path.join( + os.path.dirname(__file__), 'fixtures/auto_conf/')) + @mock.patch('utils.dockerutil.DockerUtil.client', return_value=None) + #@mock.patch.object(AbstractConfigStore, 'get_check_tpls', side_effect=_get_check_tpls) + 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)) + @mock.patch('config.get_auto_confd_path', return_value=os.path.join( os.path.dirname(__file__), 'fixtures/auto_conf/')) def test_render_template(self, mock_get_auto_confd_path): diff --git a/utils/service_discovery/abstract_config_store.py b/utils/service_discovery/abstract_config_store.py index f66dc3690f..69f2a85386 100644 --- a/utils/service_discovery/abstract_config_store.py +++ b/utils/service_discovery/abstract_config_store.py @@ -366,20 +366,25 @@ def read_config_from_store(self, identifier): return res - def _get_image_ident(self, ident): + def _get_image_ident(self, image_name): """Extract an identifier from the image""" + # See image_formats in test_service_discovery.py for supported formats + # handle exceptionnal empty ident case (docker bug) - if not ident: + if not image_name: return "" - # handle the 'redis@sha256:...' format - if '@' in ident: - return ident.split('@')[0].split('/')[-1] - # if a custom image store is used there can be a port which adds a colon - elif ident.count(':') > 1: - return ident.split(':')[1].split('/')[-1] - # otherwise we just strip the tag and keep the image name - else: - return ident.split(':')[0].split('/')[-1] + ident = image_name + # remove the @sha256: suffix if present + if '@sha' in ident: + ident = ident.split('@sha')[0] + # remove image org / store prefix, we keep the last part after '/'' + if '/' in ident: + ident = ident.split('/')[-1] + # remove the image tag after : + if ':' in ident: + ident = ident.split(':')[0] + + return ident def crawl_config_template(self): """Return whether or not configuration templates have changed since the previous crawl"""