From 28a4c9e6ff9b47b7d6a144d9e396a47421b448e8 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 26 Feb 2019 15:18:16 -0800 Subject: [PATCH 1/8] Update resource labels from GKE to K8S --- .../monitored_resource/gcp_metadata_config.py | 65 +++++++++++-------- .../monitored_resource/monitored_resource.py | 23 ++----- .../test_gcp_metadata_config.py | 35 +++++----- .../test_monitored_resource.py | 24 +++---- 4 files changed, 72 insertions(+), 75 deletions(-) diff --git a/opencensus/common/monitored_resource/gcp_metadata_config.py b/opencensus/common/monitored_resource/gcp_metadata_config.py index 0de1ef042..0c86811c2 100644 --- a/opencensus/common/monitored_resource/gcp_metadata_config.py +++ b/opencensus/common/monitored_resource/gcp_metadata_config.py @@ -12,15 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opencensus.common.http_handler import get_request import os +from opencensus.common.http_handler import get_request + _GCP_METADATA_URI = 'http://metadata/computeMetadata/v1/' _GCP_METADATA_URI_HEADER = {'Metadata-Flavor': 'Google'} # GCE common attributes -# See: https://cloud.google.com/appengine/docs/flexible/python/runtime# -# environment_variables +# See: https://cloud.google.com/appengine/docs/flexible/python/runtime#environment_variables # noqa _GCE_ATTRIBUTES = { # ProjectID is the identifier of the GCP project associated with this # resource, such as "my-project". @@ -34,17 +34,13 @@ 'zone': 'instance/zone' } -_GKE_ATTRIBUTES = { +_K8S_ATTRIBUTES = { # ProjectID is the identifier of the GCP project associated with this # resource, such as "my-project". 'project_id': 'project/project-id', - # instance_id is the numeric VM instance identifier assigned by - # Compute Engine. - 'instance_id': 'instance/id', - - # zone is the Compute Engine zone in which the VM is running. - 'zone': 'instance/zone', + # location is the Compute Engine zone in which the VM is running. + 'location': 'instance/zone', # cluster_name is the name for the cluster the container is running in. 'cluster_name': 'instance/attributes/cluster-name' @@ -52,18 +48,17 @@ # Following attributes are derived from environment variables. They are # configured via yaml file. For details refer to: -# https://cloud.google.com/kubernetes-engine/docs/tutorials/ -# custom-metrics-autoscaling#exporting_metrics_from_the_application -_GKE_ENV_ATTRIBUTES = { +# https://cloud.google.com/kubernetes-engine/docs/tutorials/custom-metrics-autoscaling#exporting_metrics_from_the_application # noqa +_K8S_ENV_ATTRIBUTES = { # ContainerName is the name of the container. 'container_name': 'CONTAINER_NAME', - # namespace_id is the identifier for the cluster namespace the container + # namespace_name is the identifier for the cluster namespace the container # is running in - 'namespace_id': 'NAMESPACE', + 'namespace_name': 'NAMESPACE', - # pod_id is the identifier for the pod the container is running in. - 'pod_id': 'HOSTNAME' + # pod_name is the identifier for the pod the container is running in. + 'pod_name': 'HOSTNAME' } # Kubenertes environment variables @@ -72,6 +67,14 @@ gcp_metadata_map = {} +def is_k8s_environment(): + """Whether the environment is a kubernetes container. + + The KUBERNETES_SERVICE_HOST environment variable must be set. + """ + return _KUBERNETES_SERVICE_HOST in os.environ + + class GcpMetadataConfig(object): """GcpMetadata represents metadata retrieved from GCP (GKE and GCE) environment. Some attributes are retrieved from the system environment. @@ -98,8 +101,8 @@ def _initialize_metadata_service(cls): gcp_metadata_map['instance_id'] = instance_id attributes = _GCE_ATTRIBUTES - if _KUBERNETES_SERVICE_HOST in os.environ: - attributes = _GKE_ATTRIBUTES + if is_k8s_environment(): + attributes = _K8S_ATTRIBUTES # fetch attributes from metadata request for attribute_key, attribute_uri in attributes.items(): @@ -122,20 +125,20 @@ def get_gce_metadata(self): return dict() - def get_gke_metadata(self): - """for GCP GKE container.""" - gke_metadata = {} + def get_k8s_metadata(self): + """Get kubernetes container metadata, as on GCP GKE.""" + k8s_metadata = {} if self.is_running_on_gcp(): - gke_metadata = gcp_metadata_map + k8s_metadata = gcp_metadata_map # fetch attributes from Environment Variables - for attribute_key, attribute_env in _GKE_ENV_ATTRIBUTES.items(): + for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items(): attribute_value = os.environ.get(attribute_env) if attribute_value is not None: - gke_metadata[attribute_key] = attribute_value + k8s_metadata[attribute_key] = attribute_value - return gke_metadata + return k8s_metadata @staticmethod def _get_attribute(attribute_key): @@ -145,8 +148,14 @@ def _get_attribute(attribute_key): computeMetadata/v1 prefix :return: The value read from the metadata service or None """ - attribute_value = get_request(_GCP_METADATA_URI + - _GKE_ATTRIBUTES[attribute_key], + if is_k8s_environment(): + try: + attr_slug = _K8S_ATTRIBUTES[attribute_key] + except KeyError: + attr_slug = _GCE_ATTRIBUTES[attribute_key] + else: + attr_slug = _GCE_ATTRIBUTES[attribute_key] + attribute_value = get_request(_GCP_METADATA_URI + attr_slug, _GCP_METADATA_URI_HEADER) if attribute_value is not None and isinstance(attribute_value, bytes): diff --git a/opencensus/common/monitored_resource/monitored_resource.py b/opencensus/common/monitored_resource/monitored_resource.py index 7dd062cb0..3ad6570ba 100644 --- a/opencensus/common/monitored_resource/monitored_resource.py +++ b/opencensus/common/monitored_resource/monitored_resource.py @@ -21,20 +21,9 @@ # Supported environments (resource types) _GCE_INSTANCE = "gce_instance" -_GKE_CONTAINER = "gke_container" +_K8S_CONTAINER = "k8s_container" _AWS_EC2_INSTANCE = "aws_ec2_instance" -# Kubenertes environment variables -_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST' - - -def is_gke_environment(): - """Whether the environment is a GKE container instance. - - The KUBERNETES_SERVICE_HOST environment variable must be set. - """ - return _KUBERNETES_SERVICE_HOST in os.environ - def is_gce_environment(): """Whether the environment is a virtual machine on GCE.""" @@ -54,8 +43,8 @@ def get_instance(): Supported environments include: - 1. 'gke_container' - - https://cloud.google.com/monitoring/api/resources#tag_gke_container + 1. 'k8s_container' + - https://cloud.google.com/monitoring/api/resources#tag_k8s_container 2. 'gce_instance' - https://cloud.google.com/monitoring/api/resources#tag_gce_instance 3. 'aws_ec2_instance' @@ -64,10 +53,10 @@ def get_instance(): :rtype: :class:`opencensus.common.resource.Resource` or None :return: A `Resource` configured for the current environment. """ - if is_gke_environment(): + if gcp_metadata_config.is_k8s_environment(): return resource.Resource( - _GKE_CONTAINER, - gcp_metadata_config.GcpMetadataConfig().get_gke_metadata()) + _K8S_CONTAINER, + gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata()) if is_gce_environment(): return resource.Resource( _GCE_INSTANCE, diff --git a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py index 3a32e83ed..5cbd9605e 100644 --- a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py +++ b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py @@ -20,6 +20,7 @@ class TestGcpMetadataConfig(unittest.TestCase): + @mock.patch('opencensus.common.monitored_resource.' 'gcp_metadata_config.get_request') def test_get_gce_metadata(self, http_request_mock): @@ -51,7 +52,7 @@ def assign_attribute_value(*args, **kwargs): 'zone': 'us-east1' } - self.assertEquals(labels_list, expected_labels) + self.assertDictEqual(labels_list, expected_labels) @mock.patch('opencensus.common.monitored_resource.' 'gcp_metadata_config.get_request') @@ -88,7 +89,7 @@ def assign_attribute_value(*args, **kwargs): 'zone': 'us-east1' } - self.assertEquals(labels_list, expected_labels) + self.assertDictEqual(labels_list, expected_labels) @mock.patch.dict( os.environ, { @@ -100,7 +101,7 @@ def assign_attribute_value(*args, **kwargs): clear=True) @mock.patch('opencensus.common.monitored_resource.' 'gcp_metadata_config.get_request') - def test_get_gke_metadata(self, http_request_mock): + def test_get_k8s_metadata(self, http_request_mock): def assign_attribute_value(*args, **kwargs): attribute_uri = args[0].split('/')[-1] if attribute_uri == 'id': @@ -120,8 +121,8 @@ def assign_attribute_value(*args, **kwargs): self.assertTrue( gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) - labels_list = gcp_metadata_config.GcpMetadataConfig().get_gke_metadata( - ) + labels_list = (gcp_metadata_config.GcpMetadataConfig() + .get_k8s_metadata()) self.assertEquals(len(labels_list), 7) @@ -129,13 +130,12 @@ def assign_attribute_value(*args, **kwargs): 'instance_id': 'my-instance', 'cluster_name': 'cluster', 'project_id': 'my-project', - 'zone': 'us-east1', - 'pod_id': 'localhost', - 'namespace_id': 'namespace', + 'location': 'us-east1', + 'pod_name': 'localhost', + 'namespace_name': 'namespace', 'container_name': 'container' } - - self.assertEquals(labels_list, expected_labels) + self.assertDictEqual(labels_list, expected_labels) @mock.patch.dict( os.environ, { @@ -146,7 +146,7 @@ def assign_attribute_value(*args, **kwargs): clear=True) @mock.patch('opencensus.common.monitored_resource.' 'gcp_metadata_config.get_request') - def test_get_gke_metadata_container_empty(self, http_request_mock): + def test_get_k8s_metadata_container_empty(self, http_request_mock): def assign_attribute_value(*args, **kwargs): attribute_uri = args[0].split('/')[-1] if attribute_uri == 'id': @@ -164,7 +164,7 @@ def assign_attribute_value(*args, **kwargs): self.assertTrue( gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) - labels_list = gcp_metadata_config.GcpMetadataConfig().get_gke_metadata( + labels_list = gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata( ) self.assertEquals(len(labels_list), 5) @@ -172,12 +172,11 @@ def assign_attribute_value(*args, **kwargs): expected_labels = { 'instance_id': 'my-instance', 'project_id': 'my-project', - 'zone': 'us-east1', - 'pod_id': 'localhost', - 'namespace_id': 'namespace' + 'location': 'us-east1', + 'pod_name': 'localhost', + 'namespace_name': 'namespace' } - - self.assertEquals(labels_list, expected_labels) + self.assertDictEqual(labels_list, expected_labels) @mock.patch.dict(os.environ, clear=True) @mock.patch('opencensus.common.monitored_resource.' @@ -194,4 +193,4 @@ def test_gcp_not_running(self, http_request_mock): self.assertEquals( len(gcp_metadata_config.GcpMetadataConfig().get_gce_metadata()), 0) self.assertEquals( - len(gcp_metadata_config.GcpMetadataConfig().get_gke_metadata()), 0) + len(gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata()), 0) diff --git a/tests/unit/common/monitored_resource_util/test_monitored_resource.py b/tests/unit/common/monitored_resource_util/test_monitored_resource.py index 4f158bd1d..51c1710a8 100644 --- a/tests/unit/common/monitored_resource_util/test_monitored_resource.py +++ b/tests/unit/common/monitored_resource_util/test_monitored_resource.py @@ -27,8 +27,8 @@ def mock_mr_method(method, use): yield -def mock_use_gke(use): - return mock_mr_method('is_gke_environment', use) +def mock_use_k8s(use): + return mock_mr_method('gcp_metadata_config.is_k8s_environment', use) def mock_use_gce(use): @@ -40,8 +40,8 @@ def mock_use_aws(use): @contextmanager -def mock_gke_env(): - with mock_use_gke(True): +def mock_k8s_env(): + with mock_use_k8s(True): with mock_use_gce(False): with mock_use_aws(False): yield @@ -49,7 +49,7 @@ def mock_gke_env(): @contextmanager def mock_gce_env(): - with mock_use_gke(False): + with mock_use_k8s(False): with mock_use_gce(True): with mock_use_aws(False): yield @@ -57,7 +57,7 @@ def mock_gce_env(): @contextmanager def mock_aws_env(): - with mock_use_gke(False): + with mock_use_k8s(False): with mock_use_gce(False): with mock_use_aws(True): yield @@ -84,7 +84,7 @@ def test_gcp_gce_monitored_resource(self, gcp_metadata_mock): @mock.patch('opencensus.common.monitored_resource.monitored_resource' '.gcp_metadata_config.GcpMetadataConfig') - def test_gcp_gke_monitored_resource(self, gcp_metadata_mock): + def test_gcp_k8s_monitored_resource(self, gcp_metadata_mock): mocked_labels = { 'instance_id': 'my-instance', @@ -97,11 +97,11 @@ def test_gcp_gke_monitored_resource(self, gcp_metadata_mock): } gcp_metadata_mock.return_value = mock.Mock() - gcp_metadata_mock.return_value.get_gke_metadata.return_value =\ + gcp_metadata_mock.return_value.get_k8s_metadata.return_value =\ mocked_labels - with mock_gke_env(): + with mock_k8s_env(): resource = monitored_resource.get_instance() - self.assertEquals(resource.get_type(), 'gke_container') + self.assertEquals(resource.get_type(), 'k8s_container') self.assertEquals(resource.get_labels(), mocked_labels) @mock.patch('opencensus.common.monitored_resource.monitored_resource' @@ -123,7 +123,7 @@ def test_aws_monitored_resource(self, aws_metadata_mock): self.assertEquals(resource.get_type(), 'aws_ec2_instance') self.assertEquals(resource.get_labels(), mocked_labels) - def test_gke_environment(self): + def test_k8s_environment(self): patch = mock.patch.dict(os.environ, {'KUBERNETES_SERVICE_HOST': '127.0.0.1'}) @@ -131,7 +131,7 @@ def test_gke_environment(self): mr = monitored_resource.get_instance() self.assertIsNotNone(mr) - self.assertEqual(mr.get_type(), "gke_container") + self.assertEqual(mr.get_type(), "k8s_container") def test_gce_environment(self): patch = mock.patch( From 9468ce861ebaa7839d17928f43373076a4f9aa4d Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 26 Feb 2019 15:19:16 -0800 Subject: [PATCH 2/8] s/assertEquals/assertEqual/ in old test --- .../test_monitored_resource.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/common/monitored_resource_util/test_monitored_resource.py b/tests/unit/common/monitored_resource_util/test_monitored_resource.py index 51c1710a8..94b546abc 100644 --- a/tests/unit/common/monitored_resource_util/test_monitored_resource.py +++ b/tests/unit/common/monitored_resource_util/test_monitored_resource.py @@ -79,8 +79,8 @@ def test_gcp_gce_monitored_resource(self, gcp_metadata_mock): mocked_labels with mock_gce_env(): resource = monitored_resource.get_instance() - self.assertEquals(resource.get_type(), 'gce_instance') - self.assertEquals(resource.get_labels(), mocked_labels) + self.assertEqual(resource.get_type(), 'gce_instance') + self.assertEqual(resource.get_labels(), mocked_labels) @mock.patch('opencensus.common.monitored_resource.monitored_resource' '.gcp_metadata_config.GcpMetadataConfig') @@ -101,8 +101,8 @@ def test_gcp_k8s_monitored_resource(self, gcp_metadata_mock): mocked_labels with mock_k8s_env(): resource = monitored_resource.get_instance() - self.assertEquals(resource.get_type(), 'k8s_container') - self.assertEquals(resource.get_labels(), mocked_labels) + self.assertEqual(resource.get_type(), 'k8s_container') + self.assertEqual(resource.get_labels(), mocked_labels) @mock.patch('opencensus.common.monitored_resource.monitored_resource' '.aws_identity_doc_utils.AwsIdentityDocumentUtils') @@ -120,8 +120,8 @@ def test_aws_monitored_resource(self, aws_metadata_mock): with mock_aws_env(): resource = monitored_resource.get_instance() - self.assertEquals(resource.get_type(), 'aws_ec2_instance') - self.assertEquals(resource.get_labels(), mocked_labels) + self.assertEqual(resource.get_type(), 'aws_ec2_instance') + self.assertEqual(resource.get_labels(), mocked_labels) def test_k8s_environment(self): patch = mock.patch.dict(os.environ, From 09dfc9f41fb2e79a90575bcc37058c5c564eb8f5 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 26 Feb 2019 17:03:15 -0800 Subject: [PATCH 3/8] Liberate k8s resource detection --- .../monitored_resource/gcp_metadata_config.py | 77 ++-------------- .../common/monitored_resource/k8s_utils.py | 72 +++++++++++++++ .../monitored_resource/monitored_resource.py | 9 +- .../test_gcp_metadata_config.py | 89 ------------------ .../monitored_resource_util/test_k8s_utils.py | 90 +++++++++++++++++++ .../test_monitored_resource.py | 21 ++--- 6 files changed, 179 insertions(+), 179 deletions(-) create mode 100644 opencensus/common/monitored_resource/k8s_utils.py create mode 100644 tests/unit/common/monitored_resource_util/test_k8s_utils.py diff --git a/opencensus/common/monitored_resource/gcp_metadata_config.py b/opencensus/common/monitored_resource/gcp_metadata_config.py index 0c86811c2..cd109d6c1 100644 --- a/opencensus/common/monitored_resource/gcp_metadata_config.py +++ b/opencensus/common/monitored_resource/gcp_metadata_config.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - from opencensus.common.http_handler import get_request _GCP_METADATA_URI = 'http://metadata/computeMetadata/v1/' @@ -34,47 +32,10 @@ 'zone': 'instance/zone' } -_K8S_ATTRIBUTES = { - # ProjectID is the identifier of the GCP project associated with this - # resource, such as "my-project". - 'project_id': 'project/project-id', - - # location is the Compute Engine zone in which the VM is running. - 'location': 'instance/zone', - - # cluster_name is the name for the cluster the container is running in. - 'cluster_name': 'instance/attributes/cluster-name' -} - -# Following attributes are derived from environment variables. They are -# configured via yaml file. For details refer to: -# https://cloud.google.com/kubernetes-engine/docs/tutorials/custom-metrics-autoscaling#exporting_metrics_from_the_application # noqa -_K8S_ENV_ATTRIBUTES = { - # ContainerName is the name of the container. - 'container_name': 'CONTAINER_NAME', - - # namespace_name is the identifier for the cluster namespace the container - # is running in - 'namespace_name': 'NAMESPACE', - - # pod_name is the identifier for the pod the container is running in. - 'pod_name': 'HOSTNAME' -} - -# Kubenertes environment variables -_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST' gcp_metadata_map = {} -def is_k8s_environment(): - """Whether the environment is a kubernetes container. - - The KUBERNETES_SERVICE_HOST environment variable must be set. - """ - return _KUBERNETES_SERVICE_HOST in os.environ - - class GcpMetadataConfig(object): """GcpMetadata represents metadata retrieved from GCP (GKE and GCE) environment. Some attributes are retrieved from the system environment. @@ -93,22 +54,18 @@ def _initialize_metadata_service(cls): if cls.inited: return - instance_id = cls._get_attribute('instance_id') + instance_id = cls.get_attribute('instance/id') if instance_id is not None: cls.is_running = True gcp_metadata_map['instance_id'] = instance_id - attributes = _GCE_ATTRIBUTES - if is_k8s_environment(): - attributes = _K8S_ATTRIBUTES - # fetch attributes from metadata request - for attribute_key, attribute_uri in attributes.items(): + for attribute_key, attribute_uri in _GCE_ATTRIBUTES.items(): if attribute_key not in gcp_metadata_map: - attribute_value = cls._get_attribute(attribute_key) - if attribute_value is not None: + attribute_value = cls.get_attribute(attribute_uri) + if attribute_value is not None: # pragma: NO COVER gcp_metadata_map[attribute_key] = attribute_value cls.inited = True @@ -125,37 +82,15 @@ def get_gce_metadata(self): return dict() - def get_k8s_metadata(self): - """Get kubernetes container metadata, as on GCP GKE.""" - k8s_metadata = {} - - if self.is_running_on_gcp(): - k8s_metadata = gcp_metadata_map - - # fetch attributes from Environment Variables - for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items(): - attribute_value = os.environ.get(attribute_env) - if attribute_value is not None: - k8s_metadata[attribute_key] = attribute_value - - return k8s_metadata - @staticmethod - def _get_attribute(attribute_key): + def get_attribute(attribute_uri): """ Fetch the requested instance metadata entry. :param attribute_uri: attribute_uri: attribute name relative to the computeMetadata/v1 prefix :return: The value read from the metadata service or None """ - if is_k8s_environment(): - try: - attr_slug = _K8S_ATTRIBUTES[attribute_key] - except KeyError: - attr_slug = _GCE_ATTRIBUTES[attribute_key] - else: - attr_slug = _GCE_ATTRIBUTES[attribute_key] - attribute_value = get_request(_GCP_METADATA_URI + attr_slug, + attribute_value = get_request(_GCP_METADATA_URI + attribute_uri, _GCP_METADATA_URI_HEADER) if attribute_value is not None and isinstance(attribute_value, bytes): diff --git a/opencensus/common/monitored_resource/k8s_utils.py b/opencensus/common/monitored_resource/k8s_utils.py new file mode 100644 index 000000000..799842822 --- /dev/null +++ b/opencensus/common/monitored_resource/k8s_utils.py @@ -0,0 +1,72 @@ +# Copyright 2019, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from opencensus.common.monitored_resource import gcp_metadata_config + +_K8S_ATTRIBUTES = { + # ProjectID is the identifier of the GCP project associated with this + # resource, such as "my-project". + 'project_id': 'project/project-id', + + # location is the Compute Engine zone in which the VM is running. + 'location': 'instance/zone', + + # cluster_name is the name for the cluster the container is running in. + 'cluster_name': 'instance/attributes/cluster-name' +} + +# Following attributes are derived from environment variables. They are +# configured via yaml file. For details refer to: +# https://cloud.google.com/kubernetes-engine/docs/tutorials/custom-metrics-autoscaling#exporting_metrics_from_the_application # noqa +_K8S_ENV_ATTRIBUTES = { + # The name of the container. + 'container_name': 'CONTAINER_NAME', + + # The identifier for the cluster namespace the container is running in + 'namespace_name': 'NAMESPACE', + + # The identifier for the pod the container is running in + 'pod_name': 'HOSTNAME' +} + +# Kubenertes environment variables +_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST' + + +def is_k8s_environment(): + """Whether the environment is a kubernetes container. + + The KUBERNETES_SERVICE_HOST environment variable must be set. + """ + return _KUBERNETES_SERVICE_HOST in os.environ + + +def get_k8s_metadata(): + """Get kubernetes container metadata, as on GCP GKE.""" + k8s_metadata = {} + + for attribute_key, attribute_uri in _K8S_ATTRIBUTES.items(): + attribute_value = (gcp_metadata_config.GcpMetadataConfig + .get_attribute(attribute_uri)) + if attribute_value is not None: + k8s_metadata[attribute_key] = attribute_value + + for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items(): + attribute_value = os.environ.get(attribute_env) + if attribute_value is not None: + k8s_metadata[attribute_key] = attribute_value + + return k8s_metadata diff --git a/opencensus/common/monitored_resource/monitored_resource.py b/opencensus/common/monitored_resource/monitored_resource.py index 3ad6570ba..f1bf244ee 100644 --- a/opencensus/common/monitored_resource/monitored_resource.py +++ b/opencensus/common/monitored_resource/monitored_resource.py @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - from opencensus.common import resource from opencensus.common.monitored_resource import aws_identity_doc_utils from opencensus.common.monitored_resource import gcp_metadata_config +from opencensus.common.monitored_resource import k8s_utils # Supported environments (resource types) @@ -53,10 +52,8 @@ def get_instance(): :rtype: :class:`opencensus.common.resource.Resource` or None :return: A `Resource` configured for the current environment. """ - if gcp_metadata_config.is_k8s_environment(): - return resource.Resource( - _K8S_CONTAINER, - gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata()) + if k8s_utils.is_k8s_environment(): + return resource.Resource(_K8S_CONTAINER, k8s_utils.get_k8s_metadata()) if is_gce_environment(): return resource.Resource( _GCE_INSTANCE, diff --git a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py index 5cbd9605e..6cf96847d 100644 --- a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py +++ b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py @@ -91,93 +91,6 @@ def assign_attribute_value(*args, **kwargs): self.assertDictEqual(labels_list, expected_labels) - @mock.patch.dict( - os.environ, { - 'KUBERNETES_SERVICE_HOST': '127.0.0.1', - 'CONTAINER_NAME': 'container', - 'NAMESPACE': 'namespace', - 'HOSTNAME': 'localhost' - }, - clear=True) - @mock.patch('opencensus.common.monitored_resource.' - 'gcp_metadata_config.get_request') - def test_get_k8s_metadata(self, http_request_mock): - def assign_attribute_value(*args, **kwargs): - attribute_uri = args[0].split('/')[-1] - if attribute_uri == 'id': - return 'my-instance' - elif attribute_uri == 'project-id': - return 'my-project' - elif attribute_uri == 'cluster-name': - return 'cluster' - elif attribute_uri == 'zone': - return 'us-east1' - - http_request_mock.side_effect = assign_attribute_value - gcp_metadata_config.GcpMetadataConfig.inited = False - gcp_metadata_config.GcpMetadataConfig.is_running = False - gcp_metadata_config.gcp_metadata_map = {} - - self.assertTrue( - gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) - - labels_list = (gcp_metadata_config.GcpMetadataConfig() - .get_k8s_metadata()) - - self.assertEquals(len(labels_list), 7) - - expected_labels = { - 'instance_id': 'my-instance', - 'cluster_name': 'cluster', - 'project_id': 'my-project', - 'location': 'us-east1', - 'pod_name': 'localhost', - 'namespace_name': 'namespace', - 'container_name': 'container' - } - self.assertDictEqual(labels_list, expected_labels) - - @mock.patch.dict( - os.environ, { - 'KUBERNETES_SERVICE_HOST': '127.0.0.1', - 'NAMESPACE': 'namespace', - 'HOSTNAME': 'localhost' - }, - clear=True) - @mock.patch('opencensus.common.monitored_resource.' - 'gcp_metadata_config.get_request') - def test_get_k8s_metadata_container_empty(self, http_request_mock): - def assign_attribute_value(*args, **kwargs): - attribute_uri = args[0].split('/')[-1] - if attribute_uri == 'id': - return 'my-instance' - elif attribute_uri == 'project-id': - return 'my-project' - elif attribute_uri == 'zone': - return 'us-east1' - - http_request_mock.side_effect = assign_attribute_value - gcp_metadata_config.GcpMetadataConfig.inited = False - gcp_metadata_config.GcpMetadataConfig.is_running = False - gcp_metadata_config.gcp_metadata_map = {} - - self.assertTrue( - gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) - - labels_list = gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata( - ) - - self.assertEquals(len(labels_list), 5) - - expected_labels = { - 'instance_id': 'my-instance', - 'project_id': 'my-project', - 'location': 'us-east1', - 'pod_name': 'localhost', - 'namespace_name': 'namespace' - } - self.assertDictEqual(labels_list, expected_labels) - @mock.patch.dict(os.environ, clear=True) @mock.patch('opencensus.common.monitored_resource.' 'gcp_metadata_config.get_request') @@ -192,5 +105,3 @@ def test_gcp_not_running(self, http_request_mock): self.assertEquals( len(gcp_metadata_config.GcpMetadataConfig().get_gce_metadata()), 0) - self.assertEquals( - len(gcp_metadata_config.GcpMetadataConfig().get_k8s_metadata()), 0) diff --git a/tests/unit/common/monitored_resource_util/test_k8s_utils.py b/tests/unit/common/monitored_resource_util/test_k8s_utils.py new file mode 100644 index 000000000..f14a539e5 --- /dev/null +++ b/tests/unit/common/monitored_resource_util/test_k8s_utils.py @@ -0,0 +1,90 @@ +# Copyright 2019, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +try: + import mock +except ImportError: + from unittest import mock + +import os +import unittest + +from opencensus.common.monitored_resource import k8s_utils + + +class TestK8SUtils(unittest.TestCase): + + @mock.patch.dict( + os.environ, { + 'KUBERNETES_SERVICE_HOST': '127.0.0.1', + 'CONTAINER_NAME': 'container', + 'NAMESPACE': 'namespace', + 'HOSTNAME': 'localhost' + }, + clear=True) + @mock.patch('opencensus.common.monitored_resource.' + 'gcp_metadata_config.get_request') + def test_get_k8s_metadata(self, http_request_mock): + def assign_attribute_value(*args, **kwargs): + attribute_uri = args[0].split('/')[-1] + if attribute_uri == 'id': + return 'my-instance' + elif attribute_uri == 'project-id': + return 'my-project' + elif attribute_uri == 'cluster-name': + return 'cluster' + elif attribute_uri == 'zone': + return 'us-east1' + + http_request_mock.side_effect = assign_attribute_value + labels_list = (k8s_utils.get_k8s_metadata()) + self.assertDictEqual( + labels_list, + {'cluster_name': 'cluster', + 'project_id': 'my-project', + 'location': 'us-east1', + 'pod_name': 'localhost', + 'namespace_name': 'namespace', + 'container_name': 'container' + }) + + @mock.patch.dict( + os.environ, { + 'KUBERNETES_SERVICE_HOST': '127.0.0.1', + 'NAMESPACE': 'namespace', + 'HOSTNAME': 'localhost' + }, + clear=True) + @mock.patch('opencensus.common.monitored_resource.' + 'gcp_metadata_config.get_request') + def test_get_k8s_metadata_container_empty(self, http_request_mock): + def assign_attribute_value(*args, **kwargs): + attribute_uri = args[0].split('/')[-1] + if attribute_uri == 'id': + return 'my-instance' + elif attribute_uri == 'project-id': + return 'my-project' + elif attribute_uri == 'zone': + return 'us-east1' + + http_request_mock.side_effect = assign_attribute_value + labels_list = (k8s_utils.get_k8s_metadata()) + + self.assertDictEqual( + labels_list, + {'project_id': 'my-project', + 'location': 'us-east1', + 'pod_name': 'localhost', + 'namespace_name': 'namespace' + }) diff --git a/tests/unit/common/monitored_resource_util/test_monitored_resource.py b/tests/unit/common/monitored_resource_util/test_monitored_resource.py index 94b546abc..e434614e0 100644 --- a/tests/unit/common/monitored_resource_util/test_monitored_resource.py +++ b/tests/unit/common/monitored_resource_util/test_monitored_resource.py @@ -28,7 +28,7 @@ def mock_mr_method(method, use): def mock_use_k8s(use): - return mock_mr_method('gcp_metadata_config.is_k8s_environment', use) + return mock_mr_method('k8s_utils.is_k8s_environment', use) def mock_use_gce(use): @@ -80,12 +80,9 @@ def test_gcp_gce_monitored_resource(self, gcp_metadata_mock): with mock_gce_env(): resource = monitored_resource.get_instance() self.assertEqual(resource.get_type(), 'gce_instance') - self.assertEqual(resource.get_labels(), mocked_labels) - - @mock.patch('opencensus.common.monitored_resource.monitored_resource' - '.gcp_metadata_config.GcpMetadataConfig') - def test_gcp_k8s_monitored_resource(self, gcp_metadata_mock): + self.assertDictEqual(resource.get_labels(), mocked_labels) + def test_gcp_k8s_monitored_resource(self): mocked_labels = { 'instance_id': 'my-instance', 'cluster_name': 'cluster', @@ -96,13 +93,11 @@ def test_gcp_k8s_monitored_resource(self, gcp_metadata_mock): 'container_name': 'container' } - gcp_metadata_mock.return_value = mock.Mock() - gcp_metadata_mock.return_value.get_k8s_metadata.return_value =\ - mocked_labels - with mock_k8s_env(): - resource = monitored_resource.get_instance() + with mock_mr_method('k8s_utils.get_k8s_metadata', mocked_labels): + with mock_k8s_env(): + resource = monitored_resource.get_instance() self.assertEqual(resource.get_type(), 'k8s_container') - self.assertEqual(resource.get_labels(), mocked_labels) + self.assertDictEqual(resource.get_labels(), mocked_labels) @mock.patch('opencensus.common.monitored_resource.monitored_resource' '.aws_identity_doc_utils.AwsIdentityDocumentUtils') @@ -121,7 +116,7 @@ def test_aws_monitored_resource(self, aws_metadata_mock): with mock_aws_env(): resource = monitored_resource.get_instance() self.assertEqual(resource.get_type(), 'aws_ec2_instance') - self.assertEqual(resource.get_labels(), mocked_labels) + self.assertDictEqual(resource.get_labels(), mocked_labels) def test_k8s_environment(self): patch = mock.patch.dict(os.environ, From baa06f1eb5708bc3f2e1700d72a38b590ae317c4 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 27 Feb 2019 13:04:17 -0800 Subject: [PATCH 4/8] Remove bad k8s labels, update keys --- .../monitored_resource/gcp_metadata_config.py | 25 ++++++---- .../common/monitored_resource/k8s_utils.py | 46 ++++++++----------- .../monitored_resource_util/test_k8s_utils.py | 40 ++++------------ 3 files changed, 43 insertions(+), 68 deletions(-) diff --git a/opencensus/common/monitored_resource/gcp_metadata_config.py b/opencensus/common/monitored_resource/gcp_metadata_config.py index cd109d6c1..ee6e9bd9a 100644 --- a/opencensus/common/monitored_resource/gcp_metadata_config.py +++ b/opencensus/common/monitored_resource/gcp_metadata_config.py @@ -17,19 +17,24 @@ _GCP_METADATA_URI = 'http://metadata/computeMetadata/v1/' _GCP_METADATA_URI_HEADER = {'Metadata-Flavor': 'Google'} +# ID of the GCP project associated with this resource, such as "my-project" +PROJECT_ID_KEY = 'project_id' + +# Numeric VM instance identifier assigned by GCE +INSTANCE_ID_KEY = 'instance_id' + +# The GCE zone in which the VM is running +ZONE_KEY = 'zone' + +# GKE cluster name +CLUSTER_NAME_KEY = 'instance/attributes/cluster-name' + # GCE common attributes # See: https://cloud.google.com/appengine/docs/flexible/python/runtime#environment_variables # noqa _GCE_ATTRIBUTES = { - # ProjectID is the identifier of the GCP project associated with this - # resource, such as "my-project". - 'project_id': 'project/project-id', - - # instance_id is the numeric VM instance identifier assigned by - # Compute Engine. - 'instance_id': 'instance/id', - - # zone is the Compute Engine zone in which the VM is running. - 'zone': 'instance/zone' + PROJECT_ID_KEY: 'project/project-id', + INSTANCE_ID_KEY: 'instance/id', + ZONE_KEY: 'instance/zone' } diff --git a/opencensus/common/monitored_resource/k8s_utils.py b/opencensus/common/monitored_resource/k8s_utils.py index 799842822..d00590cf8 100644 --- a/opencensus/common/monitored_resource/k8s_utils.py +++ b/opencensus/common/monitored_resource/k8s_utils.py @@ -16,35 +16,28 @@ from opencensus.common.monitored_resource import gcp_metadata_config -_K8S_ATTRIBUTES = { - # ProjectID is the identifier of the GCP project associated with this - # resource, such as "my-project". - 'project_id': 'project/project-id', +# Env var that signals that we're in a kubernetes container +_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST' - # location is the Compute Engine zone in which the VM is running. - 'location': 'instance/zone', +# Name of the cluster the container is running in +CLUSTER_NAME_KEY = 'k8s.io/cluster/name' - # cluster_name is the name for the cluster the container is running in. - 'cluster_name': 'instance/attributes/cluster-name' -} +# ID of the instance the container is running on +NAMESPACE_NAME_KEY = 'k8s.io/namespace/name' -# Following attributes are derived from environment variables. They are -# configured via yaml file. For details refer to: -# https://cloud.google.com/kubernetes-engine/docs/tutorials/custom-metrics-autoscaling#exporting_metrics_from_the_application # noqa -_K8S_ENV_ATTRIBUTES = { - # The name of the container. - 'container_name': 'CONTAINER_NAME', +# Container pod ID +POD_NAME_KEY = 'k8s.io/pod/name' - # The identifier for the cluster namespace the container is running in - 'namespace_name': 'NAMESPACE', +# Container name +CONTAINER_NAME_KEY = 'k8s.io/container' - # The identifier for the pod the container is running in - 'pod_name': 'HOSTNAME' +# Attributes set from environment variables +_K8S_ENV_ATTRIBUTES = { + CONTAINER_NAME_KEY: 'CONTAINER_NAME', + NAMESPACE_NAME_KEY: 'NAMESPACE', + POD_NAME_KEY: 'HOSTNAME' } -# Kubenertes environment variables -_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST' - def is_k8s_environment(): """Whether the environment is a kubernetes container. @@ -58,11 +51,10 @@ def get_k8s_metadata(): """Get kubernetes container metadata, as on GCP GKE.""" k8s_metadata = {} - for attribute_key, attribute_uri in _K8S_ATTRIBUTES.items(): - attribute_value = (gcp_metadata_config.GcpMetadataConfig - .get_attribute(attribute_uri)) - if attribute_value is not None: - k8s_metadata[attribute_key] = attribute_value + gcp_cluster = (gcp_metadata_config.GcpMetadataConfig + .get_attribute(gcp_metadata_config.CLUSTER_NAME_KEY)) + if gcp_cluster is not None: + k8s_metadata[CLUSTER_NAME_KEY] = gcp_cluster for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items(): attribute_value = os.environ.get(attribute_env) diff --git a/tests/unit/common/monitored_resource_util/test_k8s_utils.py b/tests/unit/common/monitored_resource_util/test_k8s_utils.py index f14a539e5..e62a3c3c6 100644 --- a/tests/unit/common/monitored_resource_util/test_k8s_utils.py +++ b/tests/unit/common/monitored_resource_util/test_k8s_utils.py @@ -37,26 +37,18 @@ class TestK8SUtils(unittest.TestCase): 'gcp_metadata_config.get_request') def test_get_k8s_metadata(self, http_request_mock): def assign_attribute_value(*args, **kwargs): - attribute_uri = args[0].split('/')[-1] - if attribute_uri == 'id': - return 'my-instance' - elif attribute_uri == 'project-id': - return 'my-project' - elif attribute_uri == 'cluster-name': + if args[0].split('/')[-1] == 'cluster-name': return 'cluster' - elif attribute_uri == 'zone': - return 'us-east1' + raise AssertionError http_request_mock.side_effect = assign_attribute_value labels_list = (k8s_utils.get_k8s_metadata()) self.assertDictEqual( labels_list, - {'cluster_name': 'cluster', - 'project_id': 'my-project', - 'location': 'us-east1', - 'pod_name': 'localhost', - 'namespace_name': 'namespace', - 'container_name': 'container' + {'k8s.io/cluster/name': 'cluster', + 'k8s.io/container': 'container', + 'k8s.io/namespace/name': 'namespace', + 'k8s.io/pod/name': 'localhost' }) @mock.patch.dict( @@ -66,25 +58,11 @@ def assign_attribute_value(*args, **kwargs): 'HOSTNAME': 'localhost' }, clear=True) - @mock.patch('opencensus.common.monitored_resource.' - 'gcp_metadata_config.get_request') - def test_get_k8s_metadata_container_empty(self, http_request_mock): - def assign_attribute_value(*args, **kwargs): - attribute_uri = args[0].split('/')[-1] - if attribute_uri == 'id': - return 'my-instance' - elif attribute_uri == 'project-id': - return 'my-project' - elif attribute_uri == 'zone': - return 'us-east1' - - http_request_mock.side_effect = assign_attribute_value + def test_get_k8s_metadata_container_empty(self): labels_list = (k8s_utils.get_k8s_metadata()) self.assertDictEqual( labels_list, - {'project_id': 'my-project', - 'location': 'us-east1', - 'pod_name': 'localhost', - 'namespace_name': 'namespace' + {'k8s.io/namespace/name': 'namespace', + 'k8s.io/pod/name': 'localhost' }) From 25a623c7abd00be4f2b17ea3cfe73f8a3a11a908 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 27 Feb 2019 13:08:39 -0800 Subject: [PATCH 5/8] s/gcp_metadata_map/_GCP_METADATA_MAP --- .../common/monitored_resource/gcp_metadata_config.py | 10 +++++----- .../test_gcp_metadata_config.py | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/opencensus/common/monitored_resource/gcp_metadata_config.py b/opencensus/common/monitored_resource/gcp_metadata_config.py index ee6e9bd9a..8c2082329 100644 --- a/opencensus/common/monitored_resource/gcp_metadata_config.py +++ b/opencensus/common/monitored_resource/gcp_metadata_config.py @@ -38,7 +38,7 @@ } -gcp_metadata_map = {} +_GCP_METADATA_MAP = {} class GcpMetadataConfig(object): @@ -64,14 +64,14 @@ def _initialize_metadata_service(cls): if instance_id is not None: cls.is_running = True - gcp_metadata_map['instance_id'] = instance_id + _GCP_METADATA_MAP['instance_id'] = instance_id # fetch attributes from metadata request for attribute_key, attribute_uri in _GCE_ATTRIBUTES.items(): - if attribute_key not in gcp_metadata_map: + if attribute_key not in _GCP_METADATA_MAP: attribute_value = cls.get_attribute(attribute_uri) if attribute_value is not None: # pragma: NO COVER - gcp_metadata_map[attribute_key] = attribute_value + _GCP_METADATA_MAP[attribute_key] = attribute_value cls.inited = True @@ -83,7 +83,7 @@ def is_running_on_gcp(cls): def get_gce_metadata(self): """for GCP GCE instance""" if self.is_running_on_gcp(): - return gcp_metadata_map + return _GCP_METADATA_MAP return dict() diff --git a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py index 6cf96847d..369468058 100644 --- a/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py +++ b/tests/unit/common/monitored_resource_util/test_gcp_metadata_config.py @@ -36,7 +36,7 @@ def assign_attribute_value(*args, **kwargs): http_request_mock.side_effect = assign_attribute_value gcp_metadata_config.GcpMetadataConfig.inited = False gcp_metadata_config.GcpMetadataConfig.is_running = False - gcp_metadata_config.gcp_metadata_map = {} + gcp_metadata_config._GCP_METADATA_MAP = {} self.assertTrue( gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) @@ -73,7 +73,7 @@ def assign_attribute_value(*args, **kwargs): http_request_mock.side_effect = assign_attribute_value gcp_metadata_config.GcpMetadataConfig.inited = False gcp_metadata_config.GcpMetadataConfig.is_running = False - gcp_metadata_config.gcp_metadata_map = {} + gcp_metadata_config._GCP_METADATA_MAP = {} self.assertTrue( gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) @@ -98,7 +98,7 @@ def test_gcp_not_running(self, http_request_mock): http_request_mock.return_value = None gcp_metadata_config.GcpMetadataConfig.inited = False gcp_metadata_config.GcpMetadataConfig.is_running = False - gcp_metadata_config.gcp_metadata_map = {} + gcp_metadata_config._GCP_METADATA_MAP = {} self.assertFalse( gcp_metadata_config.GcpMetadataConfig.is_running_on_gcp()) From 67d2efe6ff8464357073ccf442d9225765f6155f Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 27 Feb 2019 13:11:13 -0800 Subject: [PATCH 6/8] Lose stackdriver references in resource core --- .../common/monitored_resource/monitored_resource.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/opencensus/common/monitored_resource/monitored_resource.py b/opencensus/common/monitored_resource/monitored_resource.py index f1bf244ee..4a89cb3fd 100644 --- a/opencensus/common/monitored_resource/monitored_resource.py +++ b/opencensus/common/monitored_resource/monitored_resource.py @@ -40,15 +40,6 @@ def get_instance(): Returns a `Resource` configured for the current environment, or None if the environment is unknown or unsupported. - Supported environments include: - - 1. 'k8s_container' - - https://cloud.google.com/monitoring/api/resources#tag_k8s_container - 2. 'gce_instance' - - https://cloud.google.com/monitoring/api/resources#tag_gce_instance - 3. 'aws_ec2_instance' - - https://cloud.google.com/monitoring/api/resources#tag_aws_ec2_instance - :rtype: :class:`opencensus.common.resource.Resource` or None :return: A `Resource` configured for the current environment. """ From 71400217d87a2a12aaf9237012dbefa3495c6bef Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 27 Feb 2019 15:25:19 -0800 Subject: [PATCH 7/8] Fix k8s container name key --- opencensus/common/monitored_resource/k8s_utils.py | 2 +- tests/unit/common/monitored_resource_util/test_k8s_utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opencensus/common/monitored_resource/k8s_utils.py b/opencensus/common/monitored_resource/k8s_utils.py index d00590cf8..f4eeb51d0 100644 --- a/opencensus/common/monitored_resource/k8s_utils.py +++ b/opencensus/common/monitored_resource/k8s_utils.py @@ -29,7 +29,7 @@ POD_NAME_KEY = 'k8s.io/pod/name' # Container name -CONTAINER_NAME_KEY = 'k8s.io/container' +CONTAINER_NAME_KEY = 'k8s.io/container/name' # Attributes set from environment variables _K8S_ENV_ATTRIBUTES = { diff --git a/tests/unit/common/monitored_resource_util/test_k8s_utils.py b/tests/unit/common/monitored_resource_util/test_k8s_utils.py index e62a3c3c6..be6686056 100644 --- a/tests/unit/common/monitored_resource_util/test_k8s_utils.py +++ b/tests/unit/common/monitored_resource_util/test_k8s_utils.py @@ -46,7 +46,7 @@ def assign_attribute_value(*args, **kwargs): self.assertDictEqual( labels_list, {'k8s.io/cluster/name': 'cluster', - 'k8s.io/container': 'container', + 'k8s.io/container/name': 'container', 'k8s.io/namespace/name': 'namespace', 'k8s.io/pod/name': 'localhost' }) From eb843fb55fbb921a0f4df499537c8c304ac50342 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Thu, 28 Feb 2019 15:49:52 -0800 Subject: [PATCH 8/8] Add note to changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e1cf8a11..484597332 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ Use `UnknownMetricFamily` for `SumData` instead of `UntypedMetricFamily`. Check if label keys and values match before exporting. - Remove min and max from Distribution. +- Replace stackdriver `gke_container` resources, see the [GKE migration + notes](https://cloud.google.com/monitoring/kubernetes-engine/migration#incompatible) + for details ## 0.2.0 Released 2019-01-18