google-cloud-privilegedaccessmanager 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {google_cloud_privilegedaccessmanager-0.2.0/google_cloud_privilegedaccessmanager.egg-info → google_cloud_privilegedaccessmanager-0.3.0}/PKG-INFO +1 -1
  2. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager/gapic_version.py +1 -1
  3. google_cloud_privilegedaccessmanager-0.3.0/google/cloud/privilegedaccessmanager_v1/__init__.py +189 -0
  4. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/gapic_version.py +1 -1
  5. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/client.py +32 -14
  6. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0/google_cloud_privilegedaccessmanager.egg-info}/PKG-INFO +1 -1
  7. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/tests/unit/gapic/privilegedaccessmanager_v1/test_privileged_access_manager.py +228 -29
  8. google_cloud_privilegedaccessmanager-0.2.0/google/cloud/privilegedaccessmanager_v1/__init__.py +0 -85
  9. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/LICENSE +0 -0
  10. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/MANIFEST.in +0 -0
  11. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/README.rst +0 -0
  12. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager/__init__.py +0 -0
  13. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager/py.typed +0 -0
  14. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/gapic_metadata.json +0 -0
  15. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/py.typed +0 -0
  16. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/__init__.py +0 -0
  17. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/__init__.py +0 -0
  18. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/async_client.py +0 -0
  19. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/pagers.py +0 -0
  20. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/__init__.py +0 -0
  21. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/base.py +0 -0
  22. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/grpc.py +0 -0
  23. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/grpc_asyncio.py +0 -0
  24. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/rest.py +0 -0
  25. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/services/privileged_access_manager/transports/rest_base.py +0 -0
  26. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/types/__init__.py +0 -0
  27. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google/cloud/privilegedaccessmanager_v1/types/privilegedaccessmanager.py +0 -0
  28. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google_cloud_privilegedaccessmanager.egg-info/SOURCES.txt +0 -0
  29. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google_cloud_privilegedaccessmanager.egg-info/dependency_links.txt +0 -0
  30. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google_cloud_privilegedaccessmanager.egg-info/not-zip-safe +0 -0
  31. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google_cloud_privilegedaccessmanager.egg-info/requires.txt +0 -0
  32. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/google_cloud_privilegedaccessmanager.egg-info/top_level.txt +0 -0
  33. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/setup.cfg +0 -0
  34. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/setup.py +0 -0
  35. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/tests/__init__.py +0 -0
  36. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/tests/unit/__init__.py +0 -0
  37. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/tests/unit/gapic/__init__.py +0 -0
  38. {google_cloud_privilegedaccessmanager-0.2.0 → google_cloud_privilegedaccessmanager-0.3.0}/tests/unit/gapic/privilegedaccessmanager_v1/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-cloud-privilegedaccessmanager
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Google Cloud Privilegedaccessmanager API client library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-privilegedaccessmanager
6
6
  Author: Google LLC
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "0.2.0" # {x-release-please-version}
16
+ __version__ = "0.3.0" # {x-release-please-version}
@@ -0,0 +1,189 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2025 Google LLC
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ import sys
17
+
18
+ import google.api_core as api_core
19
+
20
+ from google.cloud.privilegedaccessmanager_v1 import gapic_version as package_version
21
+
22
+ __version__ = package_version.__version__
23
+
24
+ if sys.version_info >= (3, 8): # pragma: NO COVER
25
+ from importlib import metadata
26
+ else: # pragma: NO COVER
27
+ # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
28
+ # this code path once we drop support for Python 3.7
29
+ import importlib_metadata as metadata
30
+
31
+ from .services.privileged_access_manager import (
32
+ PrivilegedAccessManagerAsyncClient,
33
+ PrivilegedAccessManagerClient,
34
+ )
35
+ from .types.privilegedaccessmanager import (
36
+ AccessControlEntry,
37
+ ApprovalWorkflow,
38
+ ApproveGrantRequest,
39
+ CheckOnboardingStatusRequest,
40
+ CheckOnboardingStatusResponse,
41
+ CreateEntitlementRequest,
42
+ CreateGrantRequest,
43
+ DeleteEntitlementRequest,
44
+ DenyGrantRequest,
45
+ Entitlement,
46
+ GetEntitlementRequest,
47
+ GetGrantRequest,
48
+ Grant,
49
+ Justification,
50
+ ListEntitlementsRequest,
51
+ ListEntitlementsResponse,
52
+ ListGrantsRequest,
53
+ ListGrantsResponse,
54
+ ManualApprovals,
55
+ OperationMetadata,
56
+ PrivilegedAccess,
57
+ RevokeGrantRequest,
58
+ SearchEntitlementsRequest,
59
+ SearchEntitlementsResponse,
60
+ SearchGrantsRequest,
61
+ SearchGrantsResponse,
62
+ UpdateEntitlementRequest,
63
+ )
64
+
65
+ if hasattr(api_core, "check_python_version") and hasattr(
66
+ api_core, "check_dependency_versions"
67
+ ): # pragma: NO COVER
68
+ api_core.check_python_version("google.cloud.privilegedaccessmanager_v1") # type: ignore
69
+ api_core.check_dependency_versions("google.cloud.privilegedaccessmanager_v1") # type: ignore
70
+ else: # pragma: NO COVER
71
+ # An older version of api_core is installed which does not define the
72
+ # functions above. We do equivalent checks manually.
73
+ try:
74
+ import sys
75
+ import warnings
76
+
77
+ _py_version_str = sys.version.split()[0]
78
+ _package_label = "google.cloud.privilegedaccessmanager_v1"
79
+ if sys.version_info < (3, 9):
80
+ warnings.warn(
81
+ "You are using a non-supported Python version "
82
+ + f"({_py_version_str}). Google will not post any further "
83
+ + f"updates to {_package_label} supporting this Python version. "
84
+ + "Please upgrade to the latest Python version, or at "
85
+ + f"least to Python 3.9, and then update {_package_label}.",
86
+ FutureWarning,
87
+ )
88
+ if sys.version_info[:2] == (3, 9):
89
+ warnings.warn(
90
+ f"You are using a Python version ({_py_version_str}) "
91
+ + f"which Google will stop supporting in {_package_label} in "
92
+ + "January 2026. Please "
93
+ + "upgrade to the latest Python version, or at "
94
+ + "least to Python 3.10, before then, and "
95
+ + f"then update {_package_label}.",
96
+ FutureWarning,
97
+ )
98
+
99
+ def parse_version_to_tuple(version_string: str):
100
+ """Safely converts a semantic version string to a comparable tuple of integers.
101
+ Example: "4.25.8" -> (4, 25, 8)
102
+ Ignores non-numeric parts and handles common version formats.
103
+ Args:
104
+ version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
105
+ Returns:
106
+ Tuple of integers for the parsed version string.
107
+ """
108
+ parts = []
109
+ for part in version_string.split("."):
110
+ try:
111
+ parts.append(int(part))
112
+ except ValueError:
113
+ # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
114
+ # This is a simplification compared to 'packaging.parse_version', but sufficient
115
+ # for comparing strictly numeric semantic versions.
116
+ break
117
+ return tuple(parts)
118
+
119
+ def _get_version(dependency_name):
120
+ try:
121
+ version_string: str = metadata.version(dependency_name)
122
+ parsed_version = parse_version_to_tuple(version_string)
123
+ return (parsed_version, version_string)
124
+ except Exception:
125
+ # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
126
+ # or errors during parse_version_to_tuple
127
+ return (None, "--")
128
+
129
+ _dependency_package = "google.protobuf"
130
+ _next_supported_version = "4.25.8"
131
+ _next_supported_version_tuple = (4, 25, 8)
132
+ _recommendation = " (we recommend 6.x)"
133
+ (_version_used, _version_used_string) = _get_version(_dependency_package)
134
+ if _version_used and _version_used < _next_supported_version_tuple:
135
+ warnings.warn(
136
+ f"Package {_package_label} depends on "
137
+ + f"{_dependency_package}, currently installed at version "
138
+ + f"{_version_used_string}. Future updates to "
139
+ + f"{_package_label} will require {_dependency_package} at "
140
+ + f"version {_next_supported_version} or higher{_recommendation}."
141
+ + " Please ensure "
142
+ + "that either (a) your Python environment doesn't pin the "
143
+ + f"version of {_dependency_package}, so that updates to "
144
+ + f"{_package_label} can require the higher version, or "
145
+ + "(b) you manually update your Python environment to use at "
146
+ + f"least version {_next_supported_version} of "
147
+ + f"{_dependency_package}.",
148
+ FutureWarning,
149
+ )
150
+ except Exception:
151
+ warnings.warn(
152
+ "Could not determine the version of Python "
153
+ + "currently being used. To continue receiving "
154
+ + "updates for {_package_label}, ensure you are "
155
+ + "using a supported version of Python; see "
156
+ + "https://devguide.python.org/versions/"
157
+ )
158
+
159
+ __all__ = (
160
+ "PrivilegedAccessManagerAsyncClient",
161
+ "AccessControlEntry",
162
+ "ApprovalWorkflow",
163
+ "ApproveGrantRequest",
164
+ "CheckOnboardingStatusRequest",
165
+ "CheckOnboardingStatusResponse",
166
+ "CreateEntitlementRequest",
167
+ "CreateGrantRequest",
168
+ "DeleteEntitlementRequest",
169
+ "DenyGrantRequest",
170
+ "Entitlement",
171
+ "GetEntitlementRequest",
172
+ "GetGrantRequest",
173
+ "Grant",
174
+ "Justification",
175
+ "ListEntitlementsRequest",
176
+ "ListEntitlementsResponse",
177
+ "ListGrantsRequest",
178
+ "ListGrantsResponse",
179
+ "ManualApprovals",
180
+ "OperationMetadata",
181
+ "PrivilegedAccess",
182
+ "PrivilegedAccessManagerClient",
183
+ "RevokeGrantRequest",
184
+ "SearchEntitlementsRequest",
185
+ "SearchEntitlementsResponse",
186
+ "SearchGrantsRequest",
187
+ "SearchGrantsResponse",
188
+ "UpdateEntitlementRequest",
189
+ )
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "0.2.0" # {x-release-please-version}
16
+ __version__ = "0.3.0" # {x-release-please-version}
@@ -182,6 +182,34 @@ class PrivilegedAccessManagerClient(metaclass=PrivilegedAccessManagerClientMeta)
182
182
  _DEFAULT_ENDPOINT_TEMPLATE = "privilegedaccessmanager.{UNIVERSE_DOMAIN}"
183
183
  _DEFAULT_UNIVERSE = "googleapis.com"
184
184
 
185
+ @staticmethod
186
+ def _use_client_cert_effective():
187
+ """Returns whether client certificate should be used for mTLS if the
188
+ google-auth version supports should_use_client_cert automatic mTLS enablement.
189
+
190
+ Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
191
+
192
+ Returns:
193
+ bool: whether client certificate should be used for mTLS
194
+ Raises:
195
+ ValueError: (If using a version of google-auth without should_use_client_cert and
196
+ GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
197
+ """
198
+ # check if google-auth version supports should_use_client_cert for automatic mTLS enablement
199
+ if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
200
+ return mtls.should_use_client_cert()
201
+ else: # pragma: NO COVER
202
+ # if unsupported, fallback to reading from env var
203
+ use_client_cert_str = os.getenv(
204
+ "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
205
+ ).lower()
206
+ if use_client_cert_str not in ("true", "false"):
207
+ raise ValueError(
208
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
209
+ " either `true` or `false`"
210
+ )
211
+ return use_client_cert_str == "true"
212
+
185
213
  @classmethod
186
214
  def from_service_account_info(cls, info: dict, *args, **kwargs):
187
215
  """Creates an instance of this client using the provided credentials
@@ -395,12 +423,8 @@ class PrivilegedAccessManagerClient(metaclass=PrivilegedAccessManagerClientMeta)
395
423
  )
396
424
  if client_options is None:
397
425
  client_options = client_options_lib.ClientOptions()
398
- use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
426
+ use_client_cert = PrivilegedAccessManagerClient._use_client_cert_effective()
399
427
  use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
400
- if use_client_cert not in ("true", "false"):
401
- raise ValueError(
402
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
403
- )
404
428
  if use_mtls_endpoint not in ("auto", "never", "always"):
405
429
  raise MutualTLSChannelError(
406
430
  "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
@@ -408,7 +432,7 @@ class PrivilegedAccessManagerClient(metaclass=PrivilegedAccessManagerClientMeta)
408
432
 
409
433
  # Figure out the client cert source to use.
410
434
  client_cert_source = None
411
- if use_client_cert == "true":
435
+ if use_client_cert:
412
436
  if client_options.client_cert_source:
413
437
  client_cert_source = client_options.client_cert_source
414
438
  elif mtls.has_default_client_cert_source():
@@ -440,20 +464,14 @@ class PrivilegedAccessManagerClient(metaclass=PrivilegedAccessManagerClientMeta)
440
464
  google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
441
465
  is not any of ["auto", "never", "always"].
442
466
  """
443
- use_client_cert = os.getenv(
444
- "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
445
- ).lower()
467
+ use_client_cert = PrivilegedAccessManagerClient._use_client_cert_effective()
446
468
  use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
447
469
  universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
448
- if use_client_cert not in ("true", "false"):
449
- raise ValueError(
450
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
451
- )
452
470
  if use_mtls_endpoint not in ("auto", "never", "always"):
453
471
  raise MutualTLSChannelError(
454
472
  "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
455
473
  )
456
- return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
474
+ return use_client_cert, use_mtls_endpoint, universe_domain_env
457
475
 
458
476
  @staticmethod
459
477
  def _get_client_cert_source(provided_cert_source, use_cert_flag):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-cloud-privilegedaccessmanager
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Google Cloud Privilegedaccessmanager API client library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-privilegedaccessmanager
6
6
  Author: Google LLC
@@ -179,12 +179,19 @@ def test__read_environment_variables():
179
179
  with mock.patch.dict(
180
180
  os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
181
181
  ):
182
- with pytest.raises(ValueError) as excinfo:
183
- PrivilegedAccessManagerClient._read_environment_variables()
184
- assert (
185
- str(excinfo.value)
186
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
187
- )
182
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
183
+ with pytest.raises(ValueError) as excinfo:
184
+ PrivilegedAccessManagerClient._read_environment_variables()
185
+ assert (
186
+ str(excinfo.value)
187
+ == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
188
+ )
189
+ else:
190
+ assert PrivilegedAccessManagerClient._read_environment_variables() == (
191
+ False,
192
+ "auto",
193
+ None,
194
+ )
188
195
 
189
196
  with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
190
197
  assert PrivilegedAccessManagerClient._read_environment_variables() == (
@@ -223,6 +230,107 @@ def test__read_environment_variables():
223
230
  )
224
231
 
225
232
 
233
+ def test_use_client_cert_effective():
234
+ # Test case 1: Test when `should_use_client_cert` returns True.
235
+ # We mock the `should_use_client_cert` function to simulate a scenario where
236
+ # the google-auth library supports automatic mTLS and determines that a
237
+ # client certificate should be used.
238
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
239
+ with mock.patch(
240
+ "google.auth.transport.mtls.should_use_client_cert", return_value=True
241
+ ):
242
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is True
243
+
244
+ # Test case 2: Test when `should_use_client_cert` returns False.
245
+ # We mock the `should_use_client_cert` function to simulate a scenario where
246
+ # the google-auth library supports automatic mTLS and determines that a
247
+ # client certificate should NOT be used.
248
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
249
+ with mock.patch(
250
+ "google.auth.transport.mtls.should_use_client_cert", return_value=False
251
+ ):
252
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
253
+
254
+ # Test case 3: Test when `should_use_client_cert` is unavailable and the
255
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true".
256
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
257
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}):
258
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is True
259
+
260
+ # Test case 4: Test when `should_use_client_cert` is unavailable and the
261
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false".
262
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
263
+ with mock.patch.dict(
264
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}
265
+ ):
266
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
267
+
268
+ # Test case 5: Test when `should_use_client_cert` is unavailable and the
269
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True".
270
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
271
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}):
272
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is True
273
+
274
+ # Test case 6: Test when `should_use_client_cert` is unavailable and the
275
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False".
276
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
277
+ with mock.patch.dict(
278
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"}
279
+ ):
280
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
281
+
282
+ # Test case 7: Test when `should_use_client_cert` is unavailable and the
283
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE".
284
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
285
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}):
286
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is True
287
+
288
+ # Test case 8: Test when `should_use_client_cert` is unavailable and the
289
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE".
290
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
291
+ with mock.patch.dict(
292
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"}
293
+ ):
294
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
295
+
296
+ # Test case 9: Test when `should_use_client_cert` is unavailable and the
297
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set.
298
+ # In this case, the method should return False, which is the default value.
299
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
300
+ with mock.patch.dict(os.environ, clear=True):
301
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
302
+
303
+ # Test case 10: Test when `should_use_client_cert` is unavailable and the
304
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value.
305
+ # The method should raise a ValueError as the environment variable must be either
306
+ # "true" or "false".
307
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
308
+ with mock.patch.dict(
309
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"}
310
+ ):
311
+ with pytest.raises(ValueError):
312
+ PrivilegedAccessManagerClient._use_client_cert_effective()
313
+
314
+ # Test case 11: Test when `should_use_client_cert` is available and the
315
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value.
316
+ # The method should return False as the environment variable is set to an invalid value.
317
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
318
+ with mock.patch.dict(
319
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"}
320
+ ):
321
+ assert PrivilegedAccessManagerClient._use_client_cert_effective() is False
322
+
323
+ # Test case 12: Test when `should_use_client_cert` is available and the
324
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also,
325
+ # the GOOGLE_API_CONFIG environment variable is unset.
326
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
327
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}):
328
+ with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}):
329
+ assert (
330
+ PrivilegedAccessManagerClient._use_client_cert_effective() is False
331
+ )
332
+
333
+
226
334
  def test__get_client_cert_source():
227
335
  mock_provided_cert_source = mock.Mock()
228
336
  mock_default_cert_source = mock.Mock()
@@ -612,17 +720,6 @@ def test_privileged_access_manager_client_client_options(
612
720
  == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
613
721
  )
614
722
 
615
- # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
616
- with mock.patch.dict(
617
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
618
- ):
619
- with pytest.raises(ValueError) as excinfo:
620
- client = client_class(transport=transport_name)
621
- assert (
622
- str(excinfo.value)
623
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
624
- )
625
-
626
723
  # Check the case quota_project_id is provided
627
724
  options = client_options.ClientOptions(quota_project_id="octopus")
628
725
  with mock.patch.object(transport_class, "__init__") as patched:
@@ -860,6 +957,119 @@ def test_privileged_access_manager_client_get_mtls_endpoint_and_cert_source(
860
957
  assert api_endpoint == mock_api_endpoint
861
958
  assert cert_source is None
862
959
 
960
+ # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported".
961
+ with mock.patch.dict(
962
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
963
+ ):
964
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
965
+ mock_client_cert_source = mock.Mock()
966
+ mock_api_endpoint = "foo"
967
+ options = client_options.ClientOptions(
968
+ client_cert_source=mock_client_cert_source,
969
+ api_endpoint=mock_api_endpoint,
970
+ )
971
+ api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(
972
+ options
973
+ )
974
+ assert api_endpoint == mock_api_endpoint
975
+ assert cert_source is None
976
+
977
+ # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset.
978
+ test_cases = [
979
+ (
980
+ # With workloads present in config, mTLS is enabled.
981
+ {
982
+ "version": 1,
983
+ "cert_configs": {
984
+ "workload": {
985
+ "cert_path": "path/to/cert/file",
986
+ "key_path": "path/to/key/file",
987
+ }
988
+ },
989
+ },
990
+ mock_client_cert_source,
991
+ ),
992
+ (
993
+ # With workloads not present in config, mTLS is disabled.
994
+ {
995
+ "version": 1,
996
+ "cert_configs": {},
997
+ },
998
+ None,
999
+ ),
1000
+ ]
1001
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
1002
+ for config_data, expected_cert_source in test_cases:
1003
+ env = os.environ.copy()
1004
+ env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
1005
+ with mock.patch.dict(os.environ, env, clear=True):
1006
+ config_filename = "mock_certificate_config.json"
1007
+ config_file_content = json.dumps(config_data)
1008
+ m = mock.mock_open(read_data=config_file_content)
1009
+ with mock.patch("builtins.open", m):
1010
+ with mock.patch.dict(
1011
+ os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
1012
+ ):
1013
+ mock_api_endpoint = "foo"
1014
+ options = client_options.ClientOptions(
1015
+ client_cert_source=mock_client_cert_source,
1016
+ api_endpoint=mock_api_endpoint,
1017
+ )
1018
+ (
1019
+ api_endpoint,
1020
+ cert_source,
1021
+ ) = client_class.get_mtls_endpoint_and_cert_source(options)
1022
+ assert api_endpoint == mock_api_endpoint
1023
+ assert cert_source is expected_cert_source
1024
+
1025
+ # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty).
1026
+ test_cases = [
1027
+ (
1028
+ # With workloads present in config, mTLS is enabled.
1029
+ {
1030
+ "version": 1,
1031
+ "cert_configs": {
1032
+ "workload": {
1033
+ "cert_path": "path/to/cert/file",
1034
+ "key_path": "path/to/key/file",
1035
+ }
1036
+ },
1037
+ },
1038
+ mock_client_cert_source,
1039
+ ),
1040
+ (
1041
+ # With workloads not present in config, mTLS is disabled.
1042
+ {
1043
+ "version": 1,
1044
+ "cert_configs": {},
1045
+ },
1046
+ None,
1047
+ ),
1048
+ ]
1049
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
1050
+ for config_data, expected_cert_source in test_cases:
1051
+ env = os.environ.copy()
1052
+ env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
1053
+ with mock.patch.dict(os.environ, env, clear=True):
1054
+ config_filename = "mock_certificate_config.json"
1055
+ config_file_content = json.dumps(config_data)
1056
+ m = mock.mock_open(read_data=config_file_content)
1057
+ with mock.patch("builtins.open", m):
1058
+ with mock.patch.dict(
1059
+ os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
1060
+ ):
1061
+ mock_api_endpoint = "foo"
1062
+ options = client_options.ClientOptions(
1063
+ client_cert_source=mock_client_cert_source,
1064
+ api_endpoint=mock_api_endpoint,
1065
+ )
1066
+ (
1067
+ api_endpoint,
1068
+ cert_source,
1069
+ ) = client_class.get_mtls_endpoint_and_cert_source(options)
1070
+ assert api_endpoint == mock_api_endpoint
1071
+ assert cert_source is expected_cert_source
1072
+
863
1073
  # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
864
1074
  with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
865
1075
  api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
@@ -910,18 +1120,6 @@ def test_privileged_access_manager_client_get_mtls_endpoint_and_cert_source(
910
1120
  == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
911
1121
  )
912
1122
 
913
- # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
914
- with mock.patch.dict(
915
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
916
- ):
917
- with pytest.raises(ValueError) as excinfo:
918
- client_class.get_mtls_endpoint_and_cert_source()
919
-
920
- assert (
921
- str(excinfo.value)
922
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
923
- )
924
-
925
1123
 
926
1124
  @pytest.mark.parametrize(
927
1125
  "client_class", [PrivilegedAccessManagerClient, PrivilegedAccessManagerAsyncClient]
@@ -12987,6 +13185,7 @@ def test_privileged_access_manager_grpc_asyncio_transport_channel():
12987
13185
 
12988
13186
  # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
12989
13187
  # removed from grpc/grpc_asyncio transport constructor.
13188
+ @pytest.mark.filterwarnings("ignore::FutureWarning")
12990
13189
  @pytest.mark.parametrize(
12991
13190
  "transport_class",
12992
13191
  [
@@ -1,85 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright 2025 Google LLC
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
- from google.cloud.privilegedaccessmanager_v1 import gapic_version as package_version
17
-
18
- __version__ = package_version.__version__
19
-
20
-
21
- from .services.privileged_access_manager import (
22
- PrivilegedAccessManagerAsyncClient,
23
- PrivilegedAccessManagerClient,
24
- )
25
- from .types.privilegedaccessmanager import (
26
- AccessControlEntry,
27
- ApprovalWorkflow,
28
- ApproveGrantRequest,
29
- CheckOnboardingStatusRequest,
30
- CheckOnboardingStatusResponse,
31
- CreateEntitlementRequest,
32
- CreateGrantRequest,
33
- DeleteEntitlementRequest,
34
- DenyGrantRequest,
35
- Entitlement,
36
- GetEntitlementRequest,
37
- GetGrantRequest,
38
- Grant,
39
- Justification,
40
- ListEntitlementsRequest,
41
- ListEntitlementsResponse,
42
- ListGrantsRequest,
43
- ListGrantsResponse,
44
- ManualApprovals,
45
- OperationMetadata,
46
- PrivilegedAccess,
47
- RevokeGrantRequest,
48
- SearchEntitlementsRequest,
49
- SearchEntitlementsResponse,
50
- SearchGrantsRequest,
51
- SearchGrantsResponse,
52
- UpdateEntitlementRequest,
53
- )
54
-
55
- __all__ = (
56
- "PrivilegedAccessManagerAsyncClient",
57
- "AccessControlEntry",
58
- "ApprovalWorkflow",
59
- "ApproveGrantRequest",
60
- "CheckOnboardingStatusRequest",
61
- "CheckOnboardingStatusResponse",
62
- "CreateEntitlementRequest",
63
- "CreateGrantRequest",
64
- "DeleteEntitlementRequest",
65
- "DenyGrantRequest",
66
- "Entitlement",
67
- "GetEntitlementRequest",
68
- "GetGrantRequest",
69
- "Grant",
70
- "Justification",
71
- "ListEntitlementsRequest",
72
- "ListEntitlementsResponse",
73
- "ListGrantsRequest",
74
- "ListGrantsResponse",
75
- "ManualApprovals",
76
- "OperationMetadata",
77
- "PrivilegedAccess",
78
- "PrivilegedAccessManagerClient",
79
- "RevokeGrantRequest",
80
- "SearchEntitlementsRequest",
81
- "SearchEntitlementsResponse",
82
- "SearchGrantsRequest",
83
- "SearchGrantsResponse",
84
- "UpdateEntitlementRequest",
85
- )