GeezerVison is showing github.com — feat(gapic): support mTLS certificates when available (#1071) · googleapis/google-cloud-python@c73e439
File treeExpand file treeCollapse file tree Open diff view settings packages/google-cloud-logging google/cloud/logging_v2/services tests/unit/gapic/logging_v2
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/.librarian/generator-input/noxfile.py +15-8Lines changed: 15 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 32 | 32 | ISORT_VERSION = "isort==5.11.0" | 33 | 33 | LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] | 34 | 34 |
| 35 | | -DEFAULT_PYTHON_VERSION = "3.10" | | 35 | +DEFAULT_PYTHON_VERSION = "3.14" | 36 | 36 |
| 37 | 37 | UNIT_TEST_PYTHON_VERSIONS: List[str] = [ | 38 | 38 | "3.9", | 39 | 39 | "3.10", | 40 | 40 | "3.11", | 41 | 41 | "3.12", | 42 | 42 | "3.13", | | 43 | + "3.14", | 43 | 44 | ] | 44 | 45 | UNIT_TEST_STANDARD_DEPENDENCIES = [ | 45 | 46 | "mock", | | 58 | 59 | UNIT_TEST_EXTRAS: List[str] = [] | 59 | 60 | UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} | 60 | 61 |
| 61 | | -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"] | | 62 | +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = [DEFAULT_PYTHON_VERSION] | 62 | 63 | SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ | 63 | 64 | "mock", | 64 | 65 | "pytest", | | 79 | 80 | CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() | 80 | 81 |
| 81 | 82 | nox.options.sessions = [ | 82 | | - "unit", | | 83 | + "unit-3.9", | | 84 | + "unit-3.10", | | 85 | + "unit-3.11", | | 86 | + "unit-3.12", | | 87 | + "unit-3.13", | | 88 | + "unit-3.14", | 83 | 89 | "system", | 84 | 90 | "cover", | 85 | 91 | "lint", | @@ -143,7 +149,7 @@ def format(session): | 143 | 149 | @nox.session(python=DEFAULT_PYTHON_VERSION) | 144 | 150 | def lint_setup_py(session): | 145 | 151 | """Verify that setup.py is valid (including RST check).""" | 146 | | - session.install("docutils", "pygments") | | 152 | + session.install("setuptools", "docutils", "pygments") | 147 | 153 | session.run("python", "setup.py", "check", "--restructuredtext", "--strict") | 148 | 154 |
| 149 | 155 |
| @@ -182,8 +188,8 @@ def install_unittest_dependencies(session, *constraints): | 182 | 188 | ) | 183 | 189 | def unit(session, protobuf_implementation): | 184 | 190 | # Install all test dependencies, then install this package in-place. | 185 | | - | 186 | | - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): | | 191 | + py_version = tuple([int(v) for v in session.python.split(".")]) | | 192 | + if protobuf_implementation == "cpp" and py_version >= (3, 11): | 187 | 193 | session.skip("cpp implementation is not supported in python 3.11+") | 188 | 194 |
| 189 | 195 | constraints_path = str( | @@ -383,15 +389,16 @@ def docfx(session): | 383 | 389 | ) | 384 | 390 |
| 385 | 391 |
| 386 | | -@nox.session(python="3.13") | | 392 | +@nox.session(python=DEFAULT_PYTHON_VERSION) | 387 | 393 | @nox.parametrize( | 388 | 394 | "protobuf_implementation", | 389 | 395 | ["python", "upb", "cpp"], | 390 | 396 | ) | 391 | 397 | def prerelease_deps(session, protobuf_implementation): | 392 | 398 | """Run all tests with prerelease versions of dependencies installed.""" | 393 | 399 |
| 394 | | - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): | | 400 | + py_version = tuple([int(v) for v in session.python.split(".")]) | | 401 | + if protobuf_implementation == "cpp" and py_version >= (3, 11): | 395 | 402 | session.skip("cpp implementation is not supported in python 3.11+") | 396 | 403 |
| 397 | 404 | # Install all dependencies | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/.librarian/generator-input/setup.py +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 85 | 85 | "Programming Language :: Python :: 3.10", | 86 | 86 | "Programming Language :: Python :: 3.11", | 87 | 87 | "Programming Language :: Python :: 3.12", | | 88 | + "Programming Language :: Python :: 3.13", | | 89 | + "Programming Language :: Python :: 3.14", | 88 | 90 | "Operating System :: OS Independent", | 89 | 91 | "Topic :: Internet", | 90 | 92 | ], | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/.librarian/state.yaml +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:8e2c32496077054105bd06c54a59d6a6694287bc053588e24debe6da6920ad91 | | 1 | +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 | 2 | 2 | libraries: | 3 | 3 | - id: google-cloud-logging | 4 | 4 | version: 3.13.0 | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/google/cloud/logging_v2/services/config_service_v2/client.py +32-14Lines changed: 32 additions & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -153,6 +153,34 @@ def _get_default_mtls_endpoint(api_endpoint): | 153 | 153 | _DEFAULT_ENDPOINT_TEMPLATE = "logging.{UNIVERSE_DOMAIN}" | 154 | 154 | _DEFAULT_UNIVERSE = "googleapis.com" | 155 | 155 |
| | 156 | + @staticmethod | | 157 | + def _use_client_cert_effective(): | | 158 | + """Returns whether client certificate should be used for mTLS if the | | 159 | + google-auth version supports should_use_client_cert automatic mTLS enablement. | | 160 | +
| | 161 | + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. | | 162 | +
| | 163 | + Returns: | | 164 | + bool: whether client certificate should be used for mTLS | | 165 | + Raises: | | 166 | + ValueError: (If using a version of google-auth without should_use_client_cert and | | 167 | + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) | | 168 | + """ | | 169 | + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement | | 170 | + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER | | 171 | + return mtls.should_use_client_cert() | | 172 | + else: # pragma: NO COVER | | 173 | + # if unsupported, fallback to reading from env var | | 174 | + use_client_cert_str = os.getenv( | | 175 | + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | | 176 | + ).lower() | | 177 | + if use_client_cert_str not in ("true", "false"): | | 178 | + raise ValueError( | | 179 | + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" | | 180 | + " either `true` or `false`" | | 181 | + ) | | 182 | + return use_client_cert_str == "true" | | 183 | + | 156 | 184 | @classmethod | 157 | 185 | def from_service_account_info(cls, info: dict, *args, **kwargs): | 158 | 186 | """Creates an instance of this client using the provided credentials | @@ -452,20 +480,16 @@ def get_mtls_endpoint_and_cert_source( | 452 | 480 | ) | 453 | 481 | if client_options is None: | 454 | 482 | client_options = client_options_lib.ClientOptions() | 455 | | - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") | | 483 | + use_client_cert = ConfigServiceV2Client._use_client_cert_effective() | 456 | 484 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") | 457 | | - if use_client_cert not in ("true", "false"): | 458 | | - raise ValueError( | 459 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 460 | | - ) | 461 | 485 | if use_mtls_endpoint not in ("auto", "never", "always"): | 462 | 486 | raise MutualTLSChannelError( | 463 | 487 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 464 | 488 | ) | 465 | 489 |
| 466 | 490 | # Figure out the client cert source to use. | 467 | 491 | client_cert_source = None | 468 | | - if use_client_cert == "true": | | 492 | + if use_client_cert: | 469 | 493 | if client_options.client_cert_source: | 470 | 494 | client_cert_source = client_options.client_cert_source | 471 | 495 | elif mtls.has_default_client_cert_source(): | @@ -497,20 +521,14 @@ def _read_environment_variables(): | 497 | 521 | google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT | 498 | 522 | is not any of ["auto", "never", "always"]. | 499 | 523 | """ | 500 | | - use_client_cert = os.getenv( | 501 | | - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | 502 | | - ).lower() | | 524 | + use_client_cert = ConfigServiceV2Client._use_client_cert_effective() | 503 | 525 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() | 504 | 526 | universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") | 505 | | - if use_client_cert not in ("true", "false"): | 506 | | - raise ValueError( | 507 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 508 | | - ) | 509 | 527 | if use_mtls_endpoint not in ("auto", "never", "always"): | 510 | 528 | raise MutualTLSChannelError( | 511 | 529 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 512 | 530 | ) | 513 | | - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env | | 531 | + return use_client_cert, use_mtls_endpoint, universe_domain_env | 514 | 532 |
| 515 | 533 | @staticmethod | 516 | 534 | def _get_client_cert_source(provided_cert_source, use_cert_flag): | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/google/cloud/logging_v2/services/logging_service_v2/client.py +32-14Lines changed: 32 additions & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -152,6 +152,34 @@ def _get_default_mtls_endpoint(api_endpoint): | 152 | 152 | _DEFAULT_ENDPOINT_TEMPLATE = "logging.{UNIVERSE_DOMAIN}" | 153 | 153 | _DEFAULT_UNIVERSE = "googleapis.com" | 154 | 154 |
| | 155 | + @staticmethod | | 156 | + def _use_client_cert_effective(): | | 157 | + """Returns whether client certificate should be used for mTLS if the | | 158 | + google-auth version supports should_use_client_cert automatic mTLS enablement. | | 159 | +
| | 160 | + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. | | 161 | +
| | 162 | + Returns: | | 163 | + bool: whether client certificate should be used for mTLS | | 164 | + Raises: | | 165 | + ValueError: (If using a version of google-auth without should_use_client_cert and | | 166 | + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) | | 167 | + """ | | 168 | + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement | | 169 | + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER | | 170 | + return mtls.should_use_client_cert() | | 171 | + else: # pragma: NO COVER | | 172 | + # if unsupported, fallback to reading from env var | | 173 | + use_client_cert_str = os.getenv( | | 174 | + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | | 175 | + ).lower() | | 176 | + if use_client_cert_str not in ("true", "false"): | | 177 | + raise ValueError( | | 178 | + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" | | 179 | + " either `true` or `false`" | | 180 | + ) | | 181 | + return use_client_cert_str == "true" | | 182 | + | 155 | 183 | @classmethod | 156 | 184 | def from_service_account_info(cls, info: dict, *args, **kwargs): | 157 | 185 | """Creates an instance of this client using the provided credentials | @@ -334,20 +362,16 @@ def get_mtls_endpoint_and_cert_source( | 334 | 362 | ) | 335 | 363 | if client_options is None: | 336 | 364 | client_options = client_options_lib.ClientOptions() | 337 | | - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") | | 365 | + use_client_cert = LoggingServiceV2Client._use_client_cert_effective() | 338 | 366 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") | 339 | | - if use_client_cert not in ("true", "false"): | 340 | | - raise ValueError( | 341 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 342 | | - ) | 343 | 367 | if use_mtls_endpoint not in ("auto", "never", "always"): | 344 | 368 | raise MutualTLSChannelError( | 345 | 369 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 346 | 370 | ) | 347 | 371 |
| 348 | 372 | # Figure out the client cert source to use. | 349 | 373 | client_cert_source = None | 350 | | - if use_client_cert == "true": | | 374 | + if use_client_cert: | 351 | 375 | if client_options.client_cert_source: | 352 | 376 | client_cert_source = client_options.client_cert_source | 353 | 377 | elif mtls.has_default_client_cert_source(): | @@ -379,20 +403,14 @@ def _read_environment_variables(): | 379 | 403 | google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT | 380 | 404 | is not any of ["auto", "never", "always"]. | 381 | 405 | """ | 382 | | - use_client_cert = os.getenv( | 383 | | - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | 384 | | - ).lower() | | 406 | + use_client_cert = LoggingServiceV2Client._use_client_cert_effective() | 385 | 407 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() | 386 | 408 | universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") | 387 | | - if use_client_cert not in ("true", "false"): | 388 | | - raise ValueError( | 389 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 390 | | - ) | 391 | 409 | if use_mtls_endpoint not in ("auto", "never", "always"): | 392 | 410 | raise MutualTLSChannelError( | 393 | 411 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 394 | 412 | ) | 395 | | - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env | | 413 | + return use_client_cert, use_mtls_endpoint, universe_domain_env | 396 | 414 |
| 397 | 415 | @staticmethod | 398 | 416 | def _get_client_cert_source(provided_cert_source, use_cert_flag): | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/google/cloud/logging_v2/services/metrics_service_v2/client.py +32-14Lines changed: 32 additions & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -151,6 +151,34 @@ def _get_default_mtls_endpoint(api_endpoint): | 151 | 151 | _DEFAULT_ENDPOINT_TEMPLATE = "logging.{UNIVERSE_DOMAIN}" | 152 | 152 | _DEFAULT_UNIVERSE = "googleapis.com" | 153 | 153 |
| | 154 | + @staticmethod | | 155 | + def _use_client_cert_effective(): | | 156 | + """Returns whether client certificate should be used for mTLS if the | | 157 | + google-auth version supports should_use_client_cert automatic mTLS enablement. | | 158 | +
| | 159 | + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. | | 160 | +
| | 161 | + Returns: | | 162 | + bool: whether client certificate should be used for mTLS | | 163 | + Raises: | | 164 | + ValueError: (If using a version of google-auth without should_use_client_cert and | | 165 | + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) | | 166 | + """ | | 167 | + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement | | 168 | + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER | | 169 | + return mtls.should_use_client_cert() | | 170 | + else: # pragma: NO COVER | | 171 | + # if unsupported, fallback to reading from env var | | 172 | + use_client_cert_str = os.getenv( | | 173 | + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | | 174 | + ).lower() | | 175 | + if use_client_cert_str not in ("true", "false"): | | 176 | + raise ValueError( | | 177 | + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" | | 178 | + " either `true` or `false`" | | 179 | + ) | | 180 | + return use_client_cert_str == "true" | | 181 | + | 154 | 182 | @classmethod | 155 | 183 | def from_service_account_info(cls, info: dict, *args, **kwargs): | 156 | 184 | """Creates an instance of this client using the provided credentials | @@ -333,20 +361,16 @@ def get_mtls_endpoint_and_cert_source( | 333 | 361 | ) | 334 | 362 | if client_options is None: | 335 | 363 | client_options = client_options_lib.ClientOptions() | 336 | | - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") | | 364 | + use_client_cert = MetricsServiceV2Client._use_client_cert_effective() | 337 | 365 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") | 338 | | - if use_client_cert not in ("true", "false"): | 339 | | - raise ValueError( | 340 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 341 | | - ) | 342 | 366 | if use_mtls_endpoint not in ("auto", "never", "always"): | 343 | 367 | raise MutualTLSChannelError( | 344 | 368 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 345 | 369 | ) | 346 | 370 |
| 347 | 371 | # Figure out the client cert source to use. | 348 | 372 | client_cert_source = None | 349 | | - if use_client_cert == "true": | | 373 | + if use_client_cert: | 350 | 374 | if client_options.client_cert_source: | 351 | 375 | client_cert_source = client_options.client_cert_source | 352 | 376 | elif mtls.has_default_client_cert_source(): | @@ -378,20 +402,14 @@ def _read_environment_variables(): | 378 | 402 | google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT | 379 | 403 | is not any of ["auto", "never", "always"]. | 380 | 404 | """ | 381 | | - use_client_cert = os.getenv( | 382 | | - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" | 383 | | - ).lower() | | 405 | + use_client_cert = MetricsServiceV2Client._use_client_cert_effective() | 384 | 406 | use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() | 385 | 407 | universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") | 386 | | - if use_client_cert not in ("true", "false"): | 387 | | - raise ValueError( | 388 | | - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" | 389 | | - ) | 390 | 408 | if use_mtls_endpoint not in ("auto", "never", "always"): | 391 | 409 | raise MutualTLSChannelError( | 392 | 410 | "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" | 393 | 411 | ) | 394 | | - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env | | 412 | + return use_client_cert, use_mtls_endpoint, universe_domain_env | 395 | 413 |
| 396 | 414 | @staticmethod | 397 | 415 | def _get_client_cert_source(provided_cert_source, use_cert_flag): | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/noxfile.py +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 14 | 14 | # See the License for the specific language governing permissions and | 15 | 15 | # limitations under the License. | 16 | 16 |
| | 17 | +# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` | | 18 | +# The source of truth for this file is `.librarian/generator-input` | | 19 | + | | 20 | + | 17 | 21 | # Generated by synthtool. DO NOT EDIT! | 18 | 22 |
| 19 | 23 | from __future__ import absolute_import | |
Collapse file Copy file name to clipboardExpand all lines: packages/google-cloud-logging/setup.py +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 13 | 13 | # See the License for the specific language governing permissions and | 14 | 14 | # limitations under the License. | 15 | 15 | # | | 16 | + | | 17 | +# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` | | 18 | +# The source of truth for this file is `.librarian/generator-input` | | 19 | + | 16 | 20 | import io | 17 | 21 | import os | 18 | 22 |
| |
|