Skip to content

Commit dedaff9

Browse files
fix: properly handle None from metadata server (#718)
1 parent e52d247 commit dedaff9

File tree

2 files changed

+86
-8
lines changed

2 files changed

+86
-8
lines changed

google/cloud/logging_v2/handlers/_monitored_resources.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ def _create_functions_resource():
7171
resource = Resource(
7272
type="cloud_function",
7373
labels={
74-
"project_id": project,
75-
"function_name": function_name,
74+
"project_id": project if project else "",
75+
"function_name": function_name if function_name else "",
7676
"region": region.split("/")[-1] if region else "",
7777
},
7878
)
@@ -91,7 +91,7 @@ def _create_kubernetes_resource():
9191
resource = Resource(
9292
type="k8s_container",
9393
labels={
94-
"project_id": project,
94+
"project_id": project if project else "",
9595
"location": zone if zone else "",
9696
"cluster_name": cluster_name if cluster_name else "",
9797
},
@@ -110,7 +110,7 @@ def _create_compute_resource():
110110
resource = Resource(
111111
type="gce_instance",
112112
labels={
113-
"project_id": project,
113+
"project_id": project if project else "",
114114
"instance_id": instance if instance else "",
115115
"zone": zone if zone else "",
116116
},
@@ -128,7 +128,7 @@ def _create_cloud_run_resource():
128128
resource = Resource(
129129
type="cloud_run_revision",
130130
labels={
131-
"project_id": project,
131+
"project_id": project if project else "",
132132
"service_name": os.environ.get(_CLOUD_RUN_SERVICE_ID, ""),
133133
"revision_name": os.environ.get(_CLOUD_RUN_REVISION_ID, ""),
134134
"location": region.split("/")[-1] if region else "",
@@ -148,7 +148,7 @@ def _create_app_engine_resource():
148148
resource = Resource(
149149
type="gae_app",
150150
labels={
151-
"project_id": project,
151+
"project_id": project if project else "",
152152
"module_id": os.environ.get(_GAE_SERVICE_ENV, ""),
153153
"version_id": os.environ.get(_GAE_VERSION_ENV, ""),
154154
"zone": zone if zone else "",
@@ -164,7 +164,7 @@ def _create_global_resource(project):
164164
Returns:
165165
google.cloud.logging.Resource
166166
"""
167-
return Resource(type="global", labels={"project_id": project})
167+
return Resource(type="global", labels={"project_id": project if project else ""})
168168

169169

170170
def detect_resource(project=""):

tests/unit/handlers/test__monitored_resources.py

+79-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import mock
1818
import os
19-
19+
import functools
2020

2121
from google.cloud.logging_v2.handlers._monitored_resources import (
2222
_create_functions_resource,
@@ -66,6 +66,20 @@ def _mock_metadata(self, endpoint):
6666
else:
6767
return None
6868

69+
def _mock_metadata_no_project(self, endpoint):
70+
if (
71+
endpoint == _monitored_resources._ZONE_ID
72+
or endpoint == _monitored_resources._REGION_ID
73+
):
74+
return self.LOCATION
75+
elif (
76+
endpoint == _monitored_resources._GKE_CLUSTER_NAME
77+
or endpoint == _monitored_resources._GCE_INSTANCE_ID
78+
):
79+
return self.NAME
80+
else:
81+
return None
82+
6983
def setUp(self):
7084
os.environ.clear()
7185

@@ -100,6 +114,23 @@ def test_create_modern_functions_resource(self):
100114
self.assertEqual(func_resource.labels["function_name"], self.NAME)
101115
self.assertEqual(func_resource.labels["region"], self.LOCATION)
102116

117+
def test_functions_resource_no_name(self):
118+
"""
119+
Simulate functions environment with function name returned as None
120+
https://github.com/googleapis/python-logging/pull/718
121+
"""
122+
patch = mock.patch(
123+
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
124+
wraps=self._mock_metadata_no_project,
125+
)
126+
with patch:
127+
func_resource = _create_functions_resource()
128+
129+
self.assertIsInstance(func_resource, Resource)
130+
self.assertEqual(func_resource.type, "cloud_function")
131+
self.assertEqual(func_resource.labels["project_id"], "")
132+
self.assertEqual(func_resource.labels["function_name"], "")
133+
103134
def test_create_kubernetes_resource(self):
104135

105136
patch = mock.patch(
@@ -169,6 +200,29 @@ def test_global_resource(self):
169200
self.assertEqual(resource.type, "global")
170201
self.assertEqual(resource.labels["project_id"], self.PROJECT)
171202

203+
def test_with_no_project_from_server(self):
204+
"""
205+
Ensure project_id uses an empty string if not known
206+
https://github.com/googleapis/python-logging/issues/710
207+
"""
208+
patch = mock.patch(
209+
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
210+
wraps=self._mock_metadata_no_project,
211+
)
212+
with patch:
213+
_global_resource_patched = functools.partial(_create_global_resource, None)
214+
resource_fns = [
215+
_global_resource_patched,
216+
_create_app_engine_resource,
217+
_create_cloud_run_resource,
218+
_create_compute_resource,
219+
_create_kubernetes_resource,
220+
_create_functions_resource,
221+
]
222+
for fn in resource_fns:
223+
resource = fn()
224+
self.assertEqual(resource.labels["project_id"], "")
225+
172226

173227
class Test_Resource_Detection(unittest.TestCase):
174228

@@ -189,6 +243,14 @@ def _mock_gce_metadata(self, endpoint):
189243
else:
190244
return None
191245

246+
def _mock_partial_metadata(self, endpoint):
247+
if endpoint == _monitored_resources._ZONE_ID:
248+
return "ZONE"
249+
elif endpoint == _monitored_resources._GCE_INSTANCE_ID:
250+
return "instance"
251+
else:
252+
return None
253+
192254
def setUp(self):
193255
os.environ.clear()
194256

@@ -249,3 +311,19 @@ def test_detection_unknown(self):
249311
resource = detect_resource(self.PROJECT)
250312
self.assertIsInstance(resource, Resource)
251313
self.assertEqual(resource.type, "global")
314+
315+
def test_detect_partial_data(self):
316+
"""
317+
Test case where the metadata server returns partial data
318+
"""
319+
patch = mock.patch(
320+
"google.cloud.logging_v2.handlers._monitored_resources.retrieve_metadata_server",
321+
wraps=self._mock_partial_metadata,
322+
)
323+
with patch:
324+
resource = detect_resource(self.PROJECT)
325+
self.assertIsInstance(resource, Resource)
326+
self.assertEqual(resource.type, "gce_instance")
327+
# project id not returned from metadata serve
328+
# should be empty string
329+
self.assertEqual(resource.labels["project_id"], "")

0 commit comments

Comments
 (0)