Skip to content

Commit

Permalink
fix: properly handle None from metadata server (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-sanche committed Feb 1, 2023
1 parent e52d247 commit dedaff9
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 8 deletions.
14 changes: 7 additions & 7 deletions google/cloud/logging_v2/handlers/_monitored_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 71,8 @@ def _create_functions_resource():
resource = Resource(
type="cloud_function",
labels={
"project_id": project,
"function_name": function_name,
"project_id": project if project else "",
"function_name": function_name if function_name else "",
"region": region.split("/")[-1] if region else "",
},
)
Expand All @@ -91,7 91,7 @@ def _create_kubernetes_resource():
resource = Resource(
type="k8s_container",
labels={
"project_id": project,
"project_id": project if project else "",
"location": zone if zone else "",
"cluster_name": cluster_name if cluster_name else "",
},
Expand All @@ -110,7 110,7 @@ def _create_compute_resource():
resource = Resource(
type="gce_instance",
labels={
"project_id": project,
"project_id": project if project else "",
"instance_id": instance if instance else "",
"zone": zone if zone else "",
},
Expand All @@ -128,7 128,7 @@ def _create_cloud_run_resource():
resource = Resource(
type="cloud_run_revision",
labels={
"project_id": project,
"project_id": project if project else "",
"service_name": os.environ.get(_CLOUD_RUN_SERVICE_ID, ""),
"revision_name": os.environ.get(_CLOUD_RUN_REVISION_ID, ""),
"location": region.split("/")[-1] if region else "",
Expand All @@ -148,7 148,7 @@ def _create_app_engine_resource():
resource = Resource(
type="gae_app",
labels={
"project_id": project,
"project_id": project if project else "",
"module_id": os.environ.get(_GAE_SERVICE_ENV, ""),
"version_id": os.environ.get(_GAE_VERSION_ENV, ""),
"zone": zone if zone else "",
Expand All @@ -164,7 164,7 @@ def _create_global_resource(project):
Returns:
google.cloud.logging.Resource
"""
return Resource(type="global", labels={"project_id": project})
return Resource(type="global", labels={"project_id": project if project else ""})


def detect_resource(project=""):
Expand Down
80 changes: 79 additions & 1 deletion tests/unit/handlers/test__monitored_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 16,7 @@

import mock
import os

import functools

from google.cloud.logging_v2.handlers._monitored_resources import (
_create_functions_resource,
Expand Down Expand Up @@ -66,6 66,20 @@ def _mock_metadata(self, endpoint):
else:
return None

def _mock_metadata_no_project(self, endpoint):
if (
endpoint == _monitored_resources._ZONE_ID
or endpoint == _monitored_resources._REGION_ID
):
return self.LOCATION
elif (
endpoint == _monitored_resources._GKE_CLUSTER_NAME
or endpoint == _monitored_resources._GCE_INSTANCE_ID
):
return self.NAME
else:
return None

def setUp(self):
os.environ.clear()

Expand Down Expand Up @@ -100,6 114,23 @@ def test_create_modern_functions_resource(self):
self.assertEqual(func_resource.labels["function_name"], self.NAME)
self.assertEqual(func_resource.labels["region"], self.LOCATION)

def test_functions_resource_no_name(self):
"""
Simulate functions environment with function name returned as None
https://github.com/googleapis/python-logging/pull/718
"""
patch = mock.patch(
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
wraps=self._mock_metadata_no_project,
)
with patch:
func_resource = _create_functions_resource()

self.assertIsInstance(func_resource, Resource)
self.assertEqual(func_resource.type, "cloud_function")
self.assertEqual(func_resource.labels["project_id"], "")
self.assertEqual(func_resource.labels["function_name"], "")

def test_create_kubernetes_resource(self):

patch = mock.patch(
Expand Down Expand Up @@ -169,6 200,29 @@ def test_global_resource(self):
self.assertEqual(resource.type, "global")
self.assertEqual(resource.labels["project_id"], self.PROJECT)

def test_with_no_project_from_server(self):
"""
Ensure project_id uses an empty string if not known
https://github.com/googleapis/python-logging/issues/710
"""
patch = mock.patch(
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
wraps=self._mock_metadata_no_project,
)
with patch:
_global_resource_patched = functools.partial(_create_global_resource, None)
resource_fns = [
_global_resource_patched,
_create_app_engine_resource,
_create_cloud_run_resource,
_create_compute_resource,
_create_kubernetes_resource,
_create_functions_resource,
]
for fn in resource_fns:
resource = fn()
self.assertEqual(resource.labels["project_id"], "")


class Test_Resource_Detection(unittest.TestCase):

Expand All @@ -189,6 243,14 @@ def _mock_gce_metadata(self, endpoint):
else:
return None

def _mock_partial_metadata(self, endpoint):
if endpoint == _monitored_resources._ZONE_ID:
return "ZONE"
elif endpoint == _monitored_resources._GCE_INSTANCE_ID:
return "instance"
else:
return None

def setUp(self):
os.environ.clear()

Expand Down Expand Up @@ -249,3 311,19 @@ def test_detection_unknown(self):
resource = detect_resource(self.PROJECT)
self.assertIsInstance(resource, Resource)
self.assertEqual(resource.type, "global")

def test_detect_partial_data(self):
"""
Test case where the metadata server returns partial data
"""
patch = mock.patch(
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
wraps=self._mock_partial_metadata,
)
with patch:
resource = detect_resource(self.PROJECT)
self.assertIsInstance(resource, Resource)
self.assertEqual(resource.type, "gce_instance")
# project id not returned from metadata serve
# should be empty string
self.assertEqual(resource.labels["project_id"], "")

0 comments on commit dedaff9

Please sign in to comment.