From db77e88a44ffdabd284d61775960079309071617 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Tue, 23 Mar 2021 14:12:06 -0700 Subject: [PATCH] feat: add `from_service_account_info` (#45) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/f529093e-7e5c-432b-bfc8-df2fd7eacf9c/targets - [ ] To automatically regenerate this PR, check this box. PiperOrigin-RevId: 350246057 Source-Link: https://github.com/googleapis/googleapis/commit/520682435235d9c503983a360a2090025aa47cd1 --- .github/header-checker-lint.yml | 15 + .gitignore | 4 +- .kokoro/build.sh | 26 +- .kokoro/docs/docs-presubmit.cfg | 11 + .kokoro/samples/python3.6/periodic-head.cfg | 11 + .kokoro/samples/python3.7/periodic-head.cfg | 11 + .kokoro/samples/python3.8/periodic-head.cfg | 11 + .kokoro/test-samples-against-head.sh | 28 + .kokoro/test-samples-impl.sh | 102 ++++ .kokoro/test-samples.sh | 96 +--- .kokoro/trampoline_v2.sh | 2 +- .pre-commit-config.yaml | 2 +- .trampolinerc | 1 + CONTRIBUTING.rst | 22 +- MANIFEST.in | 4 +- docs/servicedirectory_v1/lookup_service.rst | 6 + .../registration_service.rst | 11 + docs/servicedirectory_v1/services.rst | 10 +- docs/servicedirectory_v1/types.rst | 1 + .../lookup_service.rst | 6 + .../registration_service.rst | 11 + docs/servicedirectory_v1beta1/services.rst | 10 +- docs/servicedirectory_v1beta1/types.rst | 1 + .../services/lookup_service/async_client.py | 37 +- .../services/lookup_service/client.py | 46 +- .../lookup_service/transports/base.py | 18 +- .../lookup_service/transports/grpc.py | 112 ++-- .../lookup_service/transports/grpc_asyncio.py | 120 ++--- .../registration_service/async_client.py | 447 +++++++-------- .../services/registration_service/client.py | 507 ++++++++--------- .../services/registration_service/pagers.py | 59 +- .../registration_service/transports/base.py | 18 +- .../registration_service/transports/grpc.py | 112 ++-- .../transports/grpc_asyncio.py | 120 ++--- .../servicedirectory_v1/types/__init__.py | 52 +- .../servicedirectory_v1/types/endpoint.py | 2 +- .../types/lookup_service.py | 2 +- .../servicedirectory_v1/types/namespace.py | 2 +- .../types/registration_service.py | 24 +- .../servicedirectory_v1/types/service.py | 4 +- .../services/lookup_service/async_client.py | 35 +- .../services/lookup_service/client.py | 44 +- .../lookup_service/transports/base.py | 18 +- .../lookup_service/transports/grpc.py | 112 ++-- .../lookup_service/transports/grpc_asyncio.py | 120 ++--- .../registration_service/async_client.py | 441 ++++++++------- .../services/registration_service/client.py | 501 ++++++++--------- .../services/registration_service/pagers.py | 59 +- .../registration_service/transports/base.py | 18 +- .../registration_service/transports/grpc.py | 112 ++-- .../transports/grpc_asyncio.py | 120 ++--- .../types/__init__.py | 52 +- .../types/endpoint.py | 2 +- .../types/lookup_service.py | 2 +- .../types/namespace.py | 2 +- .../types/registration_service.py | 24 +- .../servicedirectory_v1beta1/types/service.py | 4 +- noxfile.py | 57 +- renovate.json | 3 +- synth.metadata | 141 +---- .../gapic/servicedirectory_v1/__init__.py | 15 + .../test_lookup_service.py | 232 +++++--- .../test_registration_service.py | 508 +++++++++++++++--- .../servicedirectory_v1beta1/__init__.py | 15 + .../test_lookup_service.py | 232 +++++--- .../test_registration_service.py | 508 +++++++++++++++--- 66 files changed, 3242 insertions(+), 2219 deletions(-) create mode 100644 .github/header-checker-lint.yml create mode 100644 .kokoro/samples/python3.6/periodic-head.cfg create mode 100644 .kokoro/samples/python3.7/periodic-head.cfg create mode 100644 .kokoro/samples/python3.8/periodic-head.cfg create mode 100755 .kokoro/test-samples-against-head.sh create mode 100755 .kokoro/test-samples-impl.sh create mode 100644 docs/servicedirectory_v1/lookup_service.rst create mode 100644 docs/servicedirectory_v1/registration_service.rst create mode 100644 docs/servicedirectory_v1beta1/lookup_service.rst create mode 100644 docs/servicedirectory_v1beta1/registration_service.rst diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml new file mode 100644 index 00000000..fc281c05 --- /dev/null +++ b/.github/header-checker-lint.yml @@ -0,0 +1,15 @@ +{"allowedCopyrightHolders": ["Google LLC"], + "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], + "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt"], + "sourceFileExtensions": [ + "ts", + "js", + "java", + "sh", + "Dockerfile", + "yaml", + "py", + "html", + "txt" + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index b9daa52f..b4243ced 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,10 @@ docs.metadata # Virtual environment env/ + +# Test logs coverage.xml -sponge_log.xml +*sponge_log.xml # System test environment variables. system_tests/local_test_setup diff --git a/.kokoro/build.sh b/.kokoro/build.sh index e41cacaf..8cca485f 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -15,7 +15,11 @@ set -eo pipefail -cd github/python-service-directory +if [[ -z "${PROJECT_ROOT:-}" ]]; then + PROJECT_ROOT="github/python-service-directory" +fi + +cd "${PROJECT_ROOT}" # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 @@ -30,16 +34,26 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") # Remove old nox -python3.6 -m pip uninstall --yes --quiet nox-automation +python3 -m pip uninstall --yes --quiet nox-automation # Install nox -python3.6 -m pip install --upgrade --quiet nox -python3.6 -m nox --version +python3 -m pip install --upgrade --quiet nox +python3 -m nox --version + +# If this is a continuous build, send the test log to the FlakyBot. +# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP +fi # If NOX_SESSION is set, it only runs the specified session, # otherwise run all the sessions. if [[ -n "${NOX_SESSION:-}" ]]; then - python3.6 -m nox -s "${NOX_SESSION:-}" + python3 -m nox -s ${NOX_SESSION:-} else - python3.6 -m nox + python3 -m nox fi diff --git a/.kokoro/docs/docs-presubmit.cfg b/.kokoro/docs/docs-presubmit.cfg index 11181078..f86878f8 100644 --- a/.kokoro/docs/docs-presubmit.cfg +++ b/.kokoro/docs/docs-presubmit.cfg @@ -15,3 +15,14 @@ env_vars: { key: "TRAMPOLINE_IMAGE_UPLOAD" value: "false" } + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-service-directory/.kokoro/build.sh" +} + +# Only run this nox session. +env_vars: { + key: "NOX_SESSION" + value: "docs docfx" +} diff --git a/.kokoro/samples/python3.6/periodic-head.cfg b/.kokoro/samples/python3.6/periodic-head.cfg new file mode 100644 index 00000000..f9cfcd33 --- /dev/null +++ b/.kokoro/samples/python3.6/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg new file mode 100644 index 00000000..f9cfcd33 --- /dev/null +++ b/.kokoro/samples/python3.7/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg new file mode 100644 index 00000000..f9cfcd33 --- /dev/null +++ b/.kokoro/samples/python3.8/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh new file mode 100755 index 00000000..2fcf2255 --- /dev/null +++ b/.kokoro/test-samples-against-head.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# +# 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 +# +# https://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. + +# A customized test runner for samples. +# +# For periodic builds, you can specify this file for testing against head. + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +cd github/python-service-directory + +exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh new file mode 100755 index 00000000..cf5de74c --- /dev/null +++ b/.kokoro/test-samples-impl.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Copyright 2021 Google LLC +# +# 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 +# +# https://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. + + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +# Exit early if samples directory doesn't exist +if [ ! -d "./samples" ]; then + echo "No tests run. `./samples` not found" + exit 0 +fi + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +# Debug: show build environment +env | grep KOKORO + +# Install nox +python3.6 -m pip install --upgrade --quiet nox + +# Use secrets acessor service account to get secrets +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" +fi + +# This script will create 3 files: +# - testing/test-env.sh +# - testing/service-account.json +# - testing/client-secrets.json +./scripts/decrypt-secrets.sh + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +echo -e "\n******************** TESTING PROJECTS ********************" + +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) +# Find all requirements.txt in the samples directory (may break on whitespace). +for file in samples/**/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # Use nox to execute the tests for the project. + python3.6 -m nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If this is a periodic build, send the test log to the FlakyBot. + # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + +done +cd "$ROOT" + +# Workaround for Kokoro permissions issue: delete secrets +rm testing/{test-env.sh,client-secrets.json,service-account.json} + +exit "$RTN" diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index d46c025f..ab68b6f4 100755 --- a/.kokoro/test-samples.sh +++ b/.kokoro/test-samples.sh @@ -13,6 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default test runner for samples. +# +# For periodic builds, we rewinds the repo to the latest release, and +# run test-samples-impl.sh. # `-e` enables the script to automatically fail when a command fails # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero @@ -24,87 +28,19 @@ cd github/python-service-directory # Run periodic samples tests at latest release if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + # preserving the test runner implementation. + cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh" + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + echo "Now we rewind the repo back to the latest release..." LATEST_RELEASE=$(git describe --abbrev=0 --tags) git checkout $LATEST_RELEASE -fi - -# Exit early if samples directory doesn't exist -if [ ! -d "./samples" ]; then - echo "No tests run. `./samples` not found" - exit 0 -fi - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Debug: show build environment -env | grep KOKORO - -# Install nox -python3.6 -m pip install --upgrade --quiet nox - -# Use secrets acessor service account to get secrets -if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then - gcloud auth activate-service-account \ - --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ - --project="cloud-devrel-kokoro-resources" -fi - -# This script will create 3 files: -# - testing/test-env.sh -# - testing/service-account.json -# - testing/client-secrets.json -./scripts/decrypt-secrets.sh - -source ./testing/test-env.sh -export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json - -# For cloud-run session, we activate the service account for gcloud sdk. -gcloud auth activate-service-account \ - --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" - -export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json - -echo -e "\n******************** TESTING PROJECTS ********************" - -# Switch to 'fail at end' to allow all tests to complete before exiting. -set +e -# Use RTN to return a non-zero value if the test fails. -RTN=0 -ROOT=$(pwd) -# Find all requirements.txt in the samples directory (may break on whitespace). -for file in samples/**/requirements.txt; do - cd "$ROOT" - # Navigate to the project folder. - file=$(dirname "$file") - cd "$file" - - echo "------------------------------------------------------------" - echo "- testing $file" - echo "------------------------------------------------------------" - - # Use nox to execute the tests for the project. - python3.6 -m nox -s "$RUN_TESTS_SESSION" - EXIT=$? - - # If this is a periodic build, send the test log to the Build Cop Bot. - # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/buildcop. - if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then - chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop - $KOKORO_GFILE_DIR/linux_amd64/buildcop + echo "The current head is: " + echo $(git rev-parse --verify HEAD) + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + # move back the test runner implementation if there's no file. + if [ ! -f .kokoro/test-samples-impl.sh ]; then + cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh fi +fi - if [[ $EXIT -ne 0 ]]; then - RTN=1 - echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" - else - echo -e "\n Testing completed.\n" - fi - -done -cd "$ROOT" - -# Workaround for Kokoro permissions issue: delete secrets -rm testing/{test-env.sh,client-secrets.json,service-account.json} - -exit "$RTN" +exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/trampoline_v2.sh b/.kokoro/trampoline_v2.sh index 719bcd5b..4af6cdc2 100755 --- a/.kokoro/trampoline_v2.sh +++ b/.kokoro/trampoline_v2.sh @@ -159,7 +159,7 @@ if [[ -n "${KOKORO_BUILD_ID:-}" ]]; then "KOKORO_GITHUB_COMMIT" "KOKORO_GITHUB_PULL_REQUEST_NUMBER" "KOKORO_GITHUB_PULL_REQUEST_COMMIT" - # For Build Cop Bot + # For FlakyBot "KOKORO_GITHUB_COMMIT_URL" "KOKORO_GITHUB_PULL_REQUEST_URL" ) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9024b15..32302e48 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.0 hooks: - id: flake8 diff --git a/.trampolinerc b/.trampolinerc index 995ee291..383b6ec8 100644 --- a/.trampolinerc +++ b/.trampolinerc @@ -24,6 +24,7 @@ required_envvars+=( pass_down_envvars+=( "STAGING_BUCKET" "V2_STAGING_BUCKET" + "NOX_SESSION" ) # Prevent unintentional override on the default image. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ec519ed3..79dac3e5 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -70,9 +70,14 @@ We use `nox `__ to instrument our tests. - To test your changes, run unit tests with ``nox``:: $ nox -s unit-2.7 - $ nox -s unit-3.7 + $ nox -s unit-3.8 $ ... +- Args to pytest can be passed through the nox command separated by a `--`. For + example, to run a single test:: + + $ nox -s unit-3.8 -- -k + .. note:: The unit tests and system tests are described in the @@ -93,8 +98,12 @@ On Debian/Ubuntu:: ************ Coding Style ************ +- We use the automatic code formatter ``black``. You can run it using + the nox session ``blacken``. This will eliminate many lint errors. Run via:: + + $ nox -s blacken -- PEP8 compliance, with exceptions defined in the linter configuration. +- PEP8 compliance is required, with exceptions defined in the linter configuration. If you have ``nox`` installed, you can test that you have not introduced any non-compliant code via:: @@ -133,13 +142,18 @@ Running System Tests - To run system tests, you can execute:: - $ nox -s system-3.7 + # Run all system tests + $ nox -s system-3.8 $ nox -s system-2.7 + # Run a single system test + $ nox -s system-3.8 -- -k + + .. note:: System tests are only configured to run under Python 2.7 and - Python 3.7. For expediency, we do not run them in older versions + Python 3.8. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local diff --git a/MANIFEST.in b/MANIFEST.in index e9e29d12..e783f4c6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -16,10 +16,10 @@ # Generated by synthtool. DO NOT EDIT! include README.rst LICENSE -recursive-include google *.json *.proto +recursive-include google *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ # Exclude scripts for samples readmegen -prune scripts/readme-gen \ No newline at end of file +prune scripts/readme-gen diff --git a/docs/servicedirectory_v1/lookup_service.rst b/docs/servicedirectory_v1/lookup_service.rst new file mode 100644 index 00000000..a71b7da8 --- /dev/null +++ b/docs/servicedirectory_v1/lookup_service.rst @@ -0,0 +1,6 @@ +LookupService +------------------------------- + +.. automodule:: google.cloud.servicedirectory_v1.services.lookup_service + :members: + :inherited-members: diff --git a/docs/servicedirectory_v1/registration_service.rst b/docs/servicedirectory_v1/registration_service.rst new file mode 100644 index 00000000..577ad733 --- /dev/null +++ b/docs/servicedirectory_v1/registration_service.rst @@ -0,0 +1,11 @@ +RegistrationService +------------------------------------- + +.. automodule:: google.cloud.servicedirectory_v1.services.registration_service + :members: + :inherited-members: + + +.. automodule:: google.cloud.servicedirectory_v1.services.registration_service.pagers + :members: + :inherited-members: diff --git a/docs/servicedirectory_v1/services.rst b/docs/servicedirectory_v1/services.rst index 19b54d14..be303040 100644 --- a/docs/servicedirectory_v1/services.rst +++ b/docs/servicedirectory_v1/services.rst @@ -1,9 +1,7 @@ Services for Google Cloud Servicedirectory v1 API ================================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.servicedirectory_v1.services.lookup_service - :members: - :inherited-members: -.. automodule:: google.cloud.servicedirectory_v1.services.registration_service - :members: - :inherited-members: + lookup_service + registration_service diff --git a/docs/servicedirectory_v1/types.rst b/docs/servicedirectory_v1/types.rst index 59317d4b..376220b5 100644 --- a/docs/servicedirectory_v1/types.rst +++ b/docs/servicedirectory_v1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Servicedirectory v1 API .. automodule:: google.cloud.servicedirectory_v1.types :members: + :undoc-members: :show-inheritance: diff --git a/docs/servicedirectory_v1beta1/lookup_service.rst b/docs/servicedirectory_v1beta1/lookup_service.rst new file mode 100644 index 00000000..787d8964 --- /dev/null +++ b/docs/servicedirectory_v1beta1/lookup_service.rst @@ -0,0 +1,6 @@ +LookupService +------------------------------- + +.. automodule:: google.cloud.servicedirectory_v1beta1.services.lookup_service + :members: + :inherited-members: diff --git a/docs/servicedirectory_v1beta1/registration_service.rst b/docs/servicedirectory_v1beta1/registration_service.rst new file mode 100644 index 00000000..84a41ef3 --- /dev/null +++ b/docs/servicedirectory_v1beta1/registration_service.rst @@ -0,0 +1,11 @@ +RegistrationService +------------------------------------- + +.. automodule:: google.cloud.servicedirectory_v1beta1.services.registration_service + :members: + :inherited-members: + + +.. automodule:: google.cloud.servicedirectory_v1beta1.services.registration_service.pagers + :members: + :inherited-members: diff --git a/docs/servicedirectory_v1beta1/services.rst b/docs/servicedirectory_v1beta1/services.rst index be4bb089..359795b0 100644 --- a/docs/servicedirectory_v1beta1/services.rst +++ b/docs/servicedirectory_v1beta1/services.rst @@ -1,9 +1,7 @@ Services for Google Cloud Servicedirectory v1beta1 API ====================================================== +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.servicedirectory_v1beta1.services.lookup_service - :members: - :inherited-members: -.. automodule:: google.cloud.servicedirectory_v1beta1.services.registration_service - :members: - :inherited-members: + lookup_service + registration_service diff --git a/docs/servicedirectory_v1beta1/types.rst b/docs/servicedirectory_v1beta1/types.rst index f73d42df..1a2daef4 100644 --- a/docs/servicedirectory_v1beta1/types.rst +++ b/docs/servicedirectory_v1beta1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Servicedirectory v1beta1 API .. automodule:: google.cloud.servicedirectory_v1beta1.types :members: + :undoc-members: :show-inheritance: diff --git a/google/cloud/servicedirectory_v1/services/lookup_service/async_client.py b/google/cloud/servicedirectory_v1/services/lookup_service/async_client.py index 7c0ab5b1..3a8f0368 100644 --- a/google/cloud/servicedirectory_v1/services/lookup_service/async_client.py +++ b/google/cloud/servicedirectory_v1/services/lookup_service/async_client.py @@ -78,7 +78,36 @@ class LookupServiceAsyncClient: LookupServiceClient.parse_common_location_path ) - from_service_account_file = LookupServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceAsyncClient: The constructed client. + """ + return LookupServiceClient.from_service_account_info.__func__(LookupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceAsyncClient: The constructed client. + """ + return LookupServiceClient.from_service_account_file.__func__(LookupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -155,7 +184,7 @@ async def resolve_service( considered an active developer method. Args: - request (:class:`~.lookup_service.ResolveServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.ResolveServiceRequest`): The request object. The request message for [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. Looks up a service by its name, returns the service and @@ -168,9 +197,9 @@ async def resolve_service( sent along with the request as metadata. Returns: - ~.lookup_service.ResolveServiceResponse: + google.cloud.servicedirectory_v1.types.ResolveServiceResponse: The response message for - [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. + [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/servicedirectory_v1/services/lookup_service/client.py b/google/cloud/servicedirectory_v1/services/lookup_service/client.py index a9d48a98..b2891047 100644 --- a/google/cloud/servicedirectory_v1/services/lookup_service/client.py +++ b/google/cloud/servicedirectory_v1/services/lookup_service/client.py @@ -108,6 +108,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -120,7 +136,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + LookupServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -250,10 +266,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.LookupServiceTransport]): The + transport (Union[str, LookupServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -289,21 +305,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -346,7 +358,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -364,7 +376,7 @@ def resolve_service( considered an active developer method. Args: - request (:class:`~.lookup_service.ResolveServiceRequest`): + request (google.cloud.servicedirectory_v1.types.ResolveServiceRequest): The request object. The request message for [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. Looks up a service by its name, returns the service and @@ -377,9 +389,9 @@ def resolve_service( sent along with the request as metadata. Returns: - ~.lookup_service.ResolveServiceResponse: + google.cloud.servicedirectory_v1.types.ResolveServiceResponse: The response message for - [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. + [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/servicedirectory_v1/services/lookup_service/transports/base.py b/google/cloud/servicedirectory_v1/services/lookup_service/transports/base.py index ce0a69b6..040e8ff5 100644 --- a/google/cloud/servicedirectory_v1/services/lookup_service/transports/base.py +++ b/google/cloud/servicedirectory_v1/services/lookup_service/transports/base.py @@ -69,10 +69,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -80,6 +80,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -89,20 +92,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc.py b/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc.py index ffe1b95a..4e0abde7 100644 --- a/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc.py +++ b/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc.py @@ -57,6 +57,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -87,6 +88,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -101,72 +106,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -174,17 +167,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -198,7 +182,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc_asyncio.py b/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc_asyncio.py index 62f7acd6..b3f1462f 100644 --- a/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc_asyncio.py +++ b/google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc_asyncio.py @@ -61,7 +61,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -101,6 +101,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -132,12 +133,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -146,72 +151,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -219,17 +212,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/google/cloud/servicedirectory_v1/services/registration_service/async_client.py b/google/cloud/servicedirectory_v1/services/registration_service/async_client.py index 98bdbba9..a3cf396e 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/async_client.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/async_client.py @@ -104,7 +104,36 @@ class RegistrationServiceAsyncClient: RegistrationServiceClient.parse_common_location_path ) - from_service_account_file = RegistrationServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceAsyncClient: The constructed client. + """ + return RegistrationServiceClient.from_service_account_info.__func__(RegistrationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceAsyncClient: The constructed client. + """ + return RegistrationServiceClient.from_service_account_file.__func__(RegistrationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -183,19 +212,21 @@ async def create_namespace( r"""Creates a namespace, and returns the new Namespace. Args: - request (:class:`~.registration_service.CreateNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.CreateNamespaceRequest`): The request object. The request message for [RegistrationService.CreateNamespace][google.cloud.servicedirectory.v1.RegistrationService.CreateNamespace]. parent (:class:`str`): Required. The resource name of the project and location the namespace will be created in. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (:class:`google.cloud.servicedirectory_v1.types.Namespace`): Required. A namespace with initial fields set. + This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -208,6 +239,7 @@ async def create_namespace( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``namespace_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -219,12 +251,11 @@ async def create_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -281,13 +312,14 @@ async def list_namespaces( r"""Lists all namespaces. Args: - request (:class:`~.registration_service.ListNamespacesRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.ListNamespacesRequest`): The request object. The request message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. parent (:class:`str`): Required. The resource name of the project and location whose namespaces we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -299,9 +331,9 @@ async def list_namespaces( sent along with the request as metadata. Returns: - ~.pagers.ListNamespacesAsyncPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListNamespacesAsyncPager: The response message for - [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. + [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. Iterating over this object will yield results and resolve additional pages automatically. @@ -363,12 +395,13 @@ async def get_namespace( r"""Gets a namespace. Args: - request (:class:`~.registration_service.GetNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.GetNamespaceRequest`): The request object. The request message for [RegistrationService.GetNamespace][google.cloud.servicedirectory.v1.RegistrationService.GetNamespace]. name (:class:`str`): Required. The name of the namespace to retrieve. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -380,12 +413,11 @@ async def get_namespace( sent along with the request as metadata. Returns: - ~.namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -439,17 +471,18 @@ async def update_namespace( r"""Updates a namespace. Args: - request (:class:`~.registration_service.UpdateNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.UpdateNamespaceRequest`): The request object. The request message for [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1.RegistrationService.UpdateNamespace]. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (:class:`google.cloud.servicedirectory_v1.types.Namespace`): Required. The updated namespace. This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -461,12 +494,11 @@ async def update_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -524,12 +556,13 @@ async def delete_namespace( and endpoints in the namespace. Args: - request (:class:`~.registration_service.DeleteNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.DeleteNamespaceRequest`): The request object. The request message for [RegistrationService.DeleteNamespace][google.cloud.servicedirectory.v1.RegistrationService.DeleteNamespace]. name (:class:`str`): Required. The name of the namespace to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -591,18 +624,20 @@ async def create_service( r"""Creates a service, and returns the new Service. Args: - request (:class:`~.registration_service.CreateServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.CreateServiceRequest`): The request object. The request message for [RegistrationService.CreateService][google.cloud.servicedirectory.v1.RegistrationService.CreateService]. parent (:class:`str`): Required. The resource name of the namespace this service will belong to. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service (:class:`~.gcs_service.Service`): + service (:class:`google.cloud.servicedirectory_v1.types.Service`): Required. A service with initial fields set. + This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -615,6 +650,7 @@ async def create_service( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -626,11 +662,11 @@ async def create_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -687,13 +723,14 @@ async def list_services( r"""Lists all services belonging to a namespace. Args: - request (:class:`~.registration_service.ListServicesRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.ListServicesRequest`): The request object. The request message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. parent (:class:`str`): Required. The resource name of the namespace whose services we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -705,9 +742,9 @@ async def list_services( sent along with the request as metadata. Returns: - ~.pagers.ListServicesAsyncPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListServicesAsyncPager: The response message for - [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. + [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. Iterating over this object will yield results and resolve additional pages automatically. @@ -769,7 +806,7 @@ async def get_service( r"""Gets a service. Args: - request (:class:`~.registration_service.GetServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.GetServiceRequest`): The request object. The request message for [RegistrationService.GetService][google.cloud.servicedirectory.v1.RegistrationService.GetService]. This should not be used for looking up a service. @@ -778,6 +815,7 @@ async def get_service( name (:class:`str`): Required. The name of the service to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -789,11 +827,11 @@ async def get_service( sent along with the request as metadata. Returns: - ~.service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -847,17 +885,18 @@ async def update_service( r"""Updates a service. Args: - request (:class:`~.registration_service.UpdateServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.UpdateServiceRequest`): The request object. The request message for [RegistrationService.UpdateService][google.cloud.servicedirectory.v1.RegistrationService.UpdateService]. - service (:class:`~.gcs_service.Service`): + service (:class:`google.cloud.servicedirectory_v1.types.Service`): Required. The updated service. This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -869,11 +908,11 @@ async def update_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -931,12 +970,13 @@ async def delete_service( associated with the service. Args: - request (:class:`~.registration_service.DeleteServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.DeleteServiceRequest`): The request object. The request message for [RegistrationService.DeleteService][google.cloud.servicedirectory.v1.RegistrationService.DeleteService]. name (:class:`str`): Required. The name of the service to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -998,18 +1038,20 @@ async def create_endpoint( r"""Creates a endpoint, and returns the new Endpoint. Args: - request (:class:`~.registration_service.CreateEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.CreateEndpointRequest`): The request object. The request message for [RegistrationService.CreateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.CreateEndpoint]. parent (:class:`str`): Required. The resource name of the service that this endpoint provides. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (:class:`google.cloud.servicedirectory_v1.types.Endpoint`): Required. A endpoint with initial fields set. + This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1022,6 +1064,7 @@ async def create_endpoint( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``endpoint_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1033,10 +1076,10 @@ async def create_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1093,13 +1136,14 @@ async def list_endpoints( r"""Lists all endpoints. Args: - request (:class:`~.registration_service.ListEndpointsRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.ListEndpointsRequest`): The request object. The request message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. parent (:class:`str`): Required. The resource name of the service whose endpoints we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1111,9 +1155,9 @@ async def list_endpoints( sent along with the request as metadata. Returns: - ~.pagers.ListEndpointsAsyncPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListEndpointsAsyncPager: The response message for - [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. + [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1175,7 +1219,7 @@ async def get_endpoint( r"""Gets a endpoint. Args: - request (:class:`~.registration_service.GetEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.GetEndpointRequest`): The request object. The request message for [RegistrationService.GetEndpoint][google.cloud.servicedirectory.v1.RegistrationService.GetEndpoint]. This should not be used to lookup endpoints at runtime. @@ -1183,6 +1227,7 @@ async def get_endpoint( name (:class:`str`): Required. The name of the endpoint to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1194,10 +1239,10 @@ async def get_endpoint( sent along with the request as metadata. Returns: - ~.endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1251,17 +1296,18 @@ async def update_endpoint( r"""Updates a endpoint. Args: - request (:class:`~.registration_service.UpdateEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.UpdateEndpointRequest`): The request object. The request message for [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.UpdateEndpoint]. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (:class:`google.cloud.servicedirectory_v1.types.Endpoint`): Required. The updated endpoint. This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1273,10 +1319,10 @@ async def update_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1333,12 +1379,13 @@ async def delete_endpoint( r"""Deletes a endpoint. Args: - request (:class:`~.registration_service.DeleteEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1.types.DeleteEndpointRequest`): The request object. The request message for [RegistrationService.DeleteEndpoint][google.cloud.servicedirectory.v1.RegistrationService.DeleteEndpoint]. name (:class:`str`): Required. The name of the endpoint to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1398,7 +1445,7 @@ async def get_iam_policy( service only). Args: - request (:class:`~.iam_policy.GetIamPolicyRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.GetIamPolicyRequest`): The request object. Request message for `GetIamPolicy` method. @@ -1409,72 +1456,62 @@ async def get_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. @@ -1516,7 +1553,7 @@ async def set_iam_policy( service only). Args: - request (:class:`~.iam_policy.SetIamPolicyRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.SetIamPolicyRequest`): The request object. Request message for `SetIamPolicy` method. @@ -1527,72 +1564,62 @@ async def set_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. @@ -1634,7 +1661,7 @@ async def test_iam_permissions( service only). Args: - request (:class:`~.iam_policy.TestIamPermissionsRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest`): The request object. Request message for `TestIamPermissions` method. @@ -1645,8 +1672,8 @@ async def test_iam_permissions( sent along with the request as metadata. Returns: - ~.iam_policy.TestIamPermissionsResponse: - Response message for ``TestIamPermissions`` method. + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/servicedirectory_v1/services/registration_service/client.py b/google/cloud/servicedirectory_v1/services/registration_service/client.py index b25b0be2..f64ef5a2 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/client.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/client.py @@ -136,6 +136,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -148,7 +164,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + RegistrationServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -294,10 +310,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.RegistrationServiceTransport]): The + transport (Union[str, RegistrationServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -333,21 +349,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -390,7 +402,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -409,23 +421,25 @@ def create_namespace( r"""Creates a namespace, and returns the new Namespace. Args: - request (:class:`~.registration_service.CreateNamespaceRequest`): + request (google.cloud.servicedirectory_v1.types.CreateNamespaceRequest): The request object. The request message for [RegistrationService.CreateNamespace][google.cloud.servicedirectory.v1.RegistrationService.CreateNamespace]. - parent (:class:`str`): + parent (str): Required. The resource name of the project and location the namespace will be created in. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (google.cloud.servicedirectory_v1.types.Namespace): Required. A namespace with initial fields set. + This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace_id (:class:`str`): + namespace_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -434,6 +448,7 @@ def create_namespace( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``namespace_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -445,12 +460,11 @@ def create_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -508,13 +522,14 @@ def list_namespaces( r"""Lists all namespaces. Args: - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1.types.ListNamespacesRequest): The request object. The request message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. - parent (:class:`str`): + parent (str): Required. The resource name of the project and location whose namespaces we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -526,9 +541,9 @@ def list_namespaces( sent along with the request as metadata. Returns: - ~.pagers.ListNamespacesPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListNamespacesPager: The response message for - [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. + [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. Iterating over this object will yield results and resolve additional pages automatically. @@ -591,12 +606,13 @@ def get_namespace( r"""Gets a namespace. Args: - request (:class:`~.registration_service.GetNamespaceRequest`): + request (google.cloud.servicedirectory_v1.types.GetNamespaceRequest): The request object. The request message for [RegistrationService.GetNamespace][google.cloud.servicedirectory.v1.RegistrationService.GetNamespace]. - name (:class:`str`): + name (str): Required. The name of the namespace to retrieve. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -608,12 +624,11 @@ def get_namespace( sent along with the request as metadata. Returns: - ~.namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -668,17 +683,18 @@ def update_namespace( r"""Updates a namespace. Args: - request (:class:`~.registration_service.UpdateNamespaceRequest`): + request (google.cloud.servicedirectory_v1.types.UpdateNamespaceRequest): The request object. The request message for [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1.RegistrationService.UpdateNamespace]. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (google.cloud.servicedirectory_v1.types.Namespace): Required. The updated namespace. This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -690,12 +706,11 @@ def update_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -754,12 +769,13 @@ def delete_namespace( and endpoints in the namespace. Args: - request (:class:`~.registration_service.DeleteNamespaceRequest`): + request (google.cloud.servicedirectory_v1.types.DeleteNamespaceRequest): The request object. The request message for [RegistrationService.DeleteNamespace][google.cloud.servicedirectory.v1.RegistrationService.DeleteNamespace]. - name (:class:`str`): + name (str): Required. The name of the namespace to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -822,22 +838,24 @@ def create_service( r"""Creates a service, and returns the new Service. Args: - request (:class:`~.registration_service.CreateServiceRequest`): + request (google.cloud.servicedirectory_v1.types.CreateServiceRequest): The request object. The request message for [RegistrationService.CreateService][google.cloud.servicedirectory.v1.RegistrationService.CreateService]. - parent (:class:`str`): + parent (str): Required. The resource name of the namespace this service will belong to. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service (:class:`~.gcs_service.Service`): + service (google.cloud.servicedirectory_v1.types.Service): Required. A service with initial fields set. + This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service_id (:class:`str`): + service_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -846,6 +864,7 @@ def create_service( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -857,11 +876,11 @@ def create_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -919,13 +938,14 @@ def list_services( r"""Lists all services belonging to a namespace. Args: - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1.types.ListServicesRequest): The request object. The request message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. - parent (:class:`str`): + parent (str): Required. The resource name of the namespace whose services we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -937,9 +957,9 @@ def list_services( sent along with the request as metadata. Returns: - ~.pagers.ListServicesPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListServicesPager: The response message for - [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. + [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1002,15 +1022,16 @@ def get_service( r"""Gets a service. Args: - request (:class:`~.registration_service.GetServiceRequest`): + request (google.cloud.servicedirectory_v1.types.GetServiceRequest): The request object. The request message for [RegistrationService.GetService][google.cloud.servicedirectory.v1.RegistrationService.GetService]. This should not be used for looking up a service. Insead, use the `resolve` method as it will contain all endpoints and associated metadata. - name (:class:`str`): + name (str): Required. The name of the service to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1022,11 +1043,11 @@ def get_service( sent along with the request as metadata. Returns: - ~.service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -1081,17 +1102,18 @@ def update_service( r"""Updates a service. Args: - request (:class:`~.registration_service.UpdateServiceRequest`): + request (google.cloud.servicedirectory_v1.types.UpdateServiceRequest): The request object. The request message for [RegistrationService.UpdateService][google.cloud.servicedirectory.v1.RegistrationService.UpdateService]. - service (:class:`~.gcs_service.Service`): + service (google.cloud.servicedirectory_v1.types.Service): Required. The updated service. This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1103,11 +1125,11 @@ def update_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -1166,12 +1188,13 @@ def delete_service( associated with the service. Args: - request (:class:`~.registration_service.DeleteServiceRequest`): + request (google.cloud.servicedirectory_v1.types.DeleteServiceRequest): The request object. The request message for [RegistrationService.DeleteService][google.cloud.servicedirectory.v1.RegistrationService.DeleteService]. - name (:class:`str`): + name (str): Required. The name of the service to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1234,22 +1257,24 @@ def create_endpoint( r"""Creates a endpoint, and returns the new Endpoint. Args: - request (:class:`~.registration_service.CreateEndpointRequest`): + request (google.cloud.servicedirectory_v1.types.CreateEndpointRequest): The request object. The request message for [RegistrationService.CreateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.CreateEndpoint]. - parent (:class:`str`): + parent (str): Required. The resource name of the service that this endpoint provides. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (google.cloud.servicedirectory_v1.types.Endpoint): Required. A endpoint with initial fields set. + This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint_id (:class:`str`): + endpoint_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -1258,6 +1283,7 @@ def create_endpoint( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``endpoint_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1269,10 +1295,10 @@ def create_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1330,13 +1356,14 @@ def list_endpoints( r"""Lists all endpoints. Args: - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1.types.ListEndpointsRequest): The request object. The request message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. - parent (:class:`str`): + parent (str): Required. The resource name of the service whose endpoints we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1348,9 +1375,9 @@ def list_endpoints( sent along with the request as metadata. Returns: - ~.pagers.ListEndpointsPager: + google.cloud.servicedirectory_v1.services.registration_service.pagers.ListEndpointsPager: The response message for - [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. + [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1413,14 +1440,15 @@ def get_endpoint( r"""Gets a endpoint. Args: - request (:class:`~.registration_service.GetEndpointRequest`): + request (google.cloud.servicedirectory_v1.types.GetEndpointRequest): The request object. The request message for [RegistrationService.GetEndpoint][google.cloud.servicedirectory.v1.RegistrationService.GetEndpoint]. This should not be used to lookup endpoints at runtime. Instead, use the `resolve` method. - name (:class:`str`): + name (str): Required. The name of the endpoint to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1432,10 +1460,10 @@ def get_endpoint( sent along with the request as metadata. Returns: - ~.endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1490,17 +1518,18 @@ def update_endpoint( r"""Updates a endpoint. Args: - request (:class:`~.registration_service.UpdateEndpointRequest`): + request (google.cloud.servicedirectory_v1.types.UpdateEndpointRequest): The request object. The request message for [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.UpdateEndpoint]. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (google.cloud.servicedirectory_v1.types.Endpoint): Required. The updated endpoint. This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1512,10 +1541,10 @@ def update_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1.Service]. The - service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1573,12 +1602,13 @@ def delete_endpoint( r"""Deletes a endpoint. Args: - request (:class:`~.registration_service.DeleteEndpointRequest`): + request (google.cloud.servicedirectory_v1.types.DeleteEndpointRequest): The request object. The request message for [RegistrationService.DeleteEndpoint][google.cloud.servicedirectory.v1.RegistrationService.DeleteEndpoint]. - name (:class:`str`): + name (str): Required. The name of the endpoint to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1639,7 +1669,7 @@ def get_iam_policy( service only). Args: - request (:class:`~.iam_policy.GetIamPolicyRequest`): + request (google.iam.v1.iam_policy_pb2.GetIamPolicyRequest): The request object. Request message for `GetIamPolicy` method. @@ -1650,80 +1680,73 @@ def get_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.GetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.GetIamPolicyRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1753,7 +1776,7 @@ def set_iam_policy( service only). Args: - request (:class:`~.iam_policy.SetIamPolicyRequest`): + request (google.iam.v1.iam_policy_pb2.SetIamPolicyRequest): The request object. Request message for `SetIamPolicy` method. @@ -1764,80 +1787,73 @@ def set_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.SetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.SetIamPolicyRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1867,7 +1883,7 @@ def test_iam_permissions( service only). Args: - request (:class:`~.iam_policy.TestIamPermissionsRequest`): + request (google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest): The request object. Request message for `TestIamPermissions` method. @@ -1878,15 +1894,18 @@ def test_iam_permissions( sent along with the request as metadata. Returns: - ~.iam_policy.TestIamPermissionsResponse: - Response message for ``TestIamPermissions`` method. + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.TestIamPermissionsRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.TestIamPermissionsRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/servicedirectory_v1/services/registration_service/pagers.py b/google/cloud/servicedirectory_v1/services/registration_service/pagers.py index 408ca521..436f2035 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/pagers.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/pagers.py @@ -15,7 +15,16 @@ # limitations under the License. # -from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple +from typing import ( + Any, + AsyncIterable, + Awaitable, + Callable, + Iterable, + Sequence, + Tuple, + Optional, +) from google.cloud.servicedirectory_v1.types import endpoint from google.cloud.servicedirectory_v1.types import namespace @@ -27,7 +36,7 @@ class ListNamespacesPager: """A pager for iterating through ``list_namespaces`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListNamespacesResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListNamespacesResponse` object, and provides an ``__iter__`` method to iterate through its ``namespaces`` field. @@ -36,7 +45,7 @@ class ListNamespacesPager: through the ``namespaces`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListNamespacesResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListNamespacesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -54,9 +63,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1.types.ListNamespacesRequest): The initial request object. - response (:class:`~.registration_service.ListNamespacesResponse`): + response (google.cloud.servicedirectory_v1.types.ListNamespacesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -89,7 +98,7 @@ class ListNamespacesAsyncPager: """A pager for iterating through ``list_namespaces`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListNamespacesResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListNamespacesResponse` object, and provides an ``__aiter__`` method to iterate through its ``namespaces`` field. @@ -98,7 +107,7 @@ class ListNamespacesAsyncPager: through the ``namespaces`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListNamespacesResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListNamespacesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -116,9 +125,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1.types.ListNamespacesRequest): The initial request object. - response (:class:`~.registration_service.ListNamespacesResponse`): + response (google.cloud.servicedirectory_v1.types.ListNamespacesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -155,7 +164,7 @@ class ListServicesPager: """A pager for iterating through ``list_services`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListServicesResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListServicesResponse` object, and provides an ``__iter__`` method to iterate through its ``services`` field. @@ -164,7 +173,7 @@ class ListServicesPager: through the ``services`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListServicesResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListServicesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -182,9 +191,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1.types.ListServicesRequest): The initial request object. - response (:class:`~.registration_service.ListServicesResponse`): + response (google.cloud.servicedirectory_v1.types.ListServicesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -217,7 +226,7 @@ class ListServicesAsyncPager: """A pager for iterating through ``list_services`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListServicesResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListServicesResponse` object, and provides an ``__aiter__`` method to iterate through its ``services`` field. @@ -226,7 +235,7 @@ class ListServicesAsyncPager: through the ``services`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListServicesResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListServicesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -244,9 +253,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1.types.ListServicesRequest): The initial request object. - response (:class:`~.registration_service.ListServicesResponse`): + response (google.cloud.servicedirectory_v1.types.ListServicesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -283,7 +292,7 @@ class ListEndpointsPager: """A pager for iterating through ``list_endpoints`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListEndpointsResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListEndpointsResponse` object, and provides an ``__iter__`` method to iterate through its ``endpoints`` field. @@ -292,7 +301,7 @@ class ListEndpointsPager: through the ``endpoints`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListEndpointsResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListEndpointsResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -310,9 +319,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1.types.ListEndpointsRequest): The initial request object. - response (:class:`~.registration_service.ListEndpointsResponse`): + response (google.cloud.servicedirectory_v1.types.ListEndpointsResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -345,7 +354,7 @@ class ListEndpointsAsyncPager: """A pager for iterating through ``list_endpoints`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListEndpointsResponse` object, and + :class:`google.cloud.servicedirectory_v1.types.ListEndpointsResponse` object, and provides an ``__aiter__`` method to iterate through its ``endpoints`` field. @@ -354,7 +363,7 @@ class ListEndpointsAsyncPager: through the ``endpoints`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListEndpointsResponse` + All the usual :class:`google.cloud.servicedirectory_v1.types.ListEndpointsResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -372,9 +381,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1.types.ListEndpointsRequest): The initial request object. - response (:class:`~.registration_service.ListEndpointsResponse`): + response (google.cloud.servicedirectory_v1.types.ListEndpointsResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. diff --git a/google/cloud/servicedirectory_v1/services/registration_service/transports/base.py b/google/cloud/servicedirectory_v1/services/registration_service/transports/base.py index 9d7294c8..621ed082 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/transports/base.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/transports/base.py @@ -78,10 +78,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -89,6 +89,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -98,20 +101,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc.py b/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc.py index fb2ade79..da0220c0 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc.py @@ -80,6 +80,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -110,6 +111,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -124,72 +129,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -197,17 +190,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -221,7 +205,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc_asyncio.py b/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc_asyncio.py index ed330707..7058c302 100644 --- a/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc_asyncio.py +++ b/google/cloud/servicedirectory_v1/services/registration_service/transports/grpc_asyncio.py @@ -84,7 +84,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -124,6 +124,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -155,12 +156,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -169,72 +174,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -242,17 +235,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/google/cloud/servicedirectory_v1/types/__init__.py b/google/cloud/servicedirectory_v1/types/__init__.py index 505b0c76..6ede60ca 100644 --- a/google/cloud/servicedirectory_v1/types/__init__.py +++ b/google/cloud/servicedirectory_v1/types/__init__.py @@ -16,55 +16,55 @@ # from .endpoint import Endpoint -from .service import Service from .lookup_service import ( ResolveServiceRequest, ResolveServiceResponse, ) from .namespace import Namespace from .registration_service import ( + CreateEndpointRequest, CreateNamespaceRequest, - ListNamespacesRequest, - ListNamespacesResponse, - GetNamespaceRequest, - UpdateNamespaceRequest, - DeleteNamespaceRequest, CreateServiceRequest, - ListServicesRequest, - ListServicesResponse, - GetServiceRequest, - UpdateServiceRequest, + DeleteEndpointRequest, + DeleteNamespaceRequest, DeleteServiceRequest, - CreateEndpointRequest, + GetEndpointRequest, + GetNamespaceRequest, + GetServiceRequest, ListEndpointsRequest, ListEndpointsResponse, - GetEndpointRequest, + ListNamespacesRequest, + ListNamespacesResponse, + ListServicesRequest, + ListServicesResponse, UpdateEndpointRequest, - DeleteEndpointRequest, + UpdateNamespaceRequest, + UpdateServiceRequest, ) +from .service import Service __all__ = ( "Endpoint", - "Service", "ResolveServiceRequest", "ResolveServiceResponse", "Namespace", + "CreateEndpointRequest", "CreateNamespaceRequest", - "ListNamespacesRequest", - "ListNamespacesResponse", - "GetNamespaceRequest", - "UpdateNamespaceRequest", - "DeleteNamespaceRequest", "CreateServiceRequest", - "ListServicesRequest", - "ListServicesResponse", - "GetServiceRequest", - "UpdateServiceRequest", + "DeleteEndpointRequest", + "DeleteNamespaceRequest", "DeleteServiceRequest", - "CreateEndpointRequest", + "GetEndpointRequest", + "GetNamespaceRequest", + "GetServiceRequest", "ListEndpointsRequest", "ListEndpointsResponse", - "GetEndpointRequest", + "ListNamespacesRequest", + "ListNamespacesResponse", + "ListServicesRequest", + "ListServicesResponse", "UpdateEndpointRequest", - "DeleteEndpointRequest", + "UpdateNamespaceRequest", + "UpdateServiceRequest", + "Service", ) diff --git a/google/cloud/servicedirectory_v1/types/endpoint.py b/google/cloud/servicedirectory_v1/types/endpoint.py index 479540c4..8ace1cf2 100644 --- a/google/cloud/servicedirectory_v1/types/endpoint.py +++ b/google/cloud/servicedirectory_v1/types/endpoint.py @@ -40,7 +40,7 @@ class Endpoint(proto.Message): port (int): Optional. Service Directory will reject values outside of [0, 65535]. - annotations (Sequence[~.endpoint.Endpoint.AnnotationsEntry]): + annotations (Sequence[google.cloud.servicedirectory_v1.types.Endpoint.AnnotationsEntry]): Optional. Annotations for the endpoint. This data can be consumed by service clients. Restrictions: diff --git a/google/cloud/servicedirectory_v1/types/lookup_service.py b/google/cloud/servicedirectory_v1/types/lookup_service.py index 884820fb..7ef338e1 100644 --- a/google/cloud/servicedirectory_v1/types/lookup_service.py +++ b/google/cloud/servicedirectory_v1/types/lookup_service.py @@ -74,7 +74,7 @@ class ResolveServiceResponse(proto.Message): [LookupService.ResolveService][google.cloud.servicedirectory.v1.LookupService.ResolveService]. Attributes: - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1.types.Service): """ diff --git a/google/cloud/servicedirectory_v1/types/namespace.py b/google/cloud/servicedirectory_v1/types/namespace.py index 56d5d575..f6cf1e89 100644 --- a/google/cloud/servicedirectory_v1/types/namespace.py +++ b/google/cloud/servicedirectory_v1/types/namespace.py @@ -33,7 +33,7 @@ class Namespace(proto.Message): name (str): Immutable. The resource name for the namespace in the format ``projects/*/locations/*/namespaces/*`` - labels (Sequence[~.namespace.Namespace.LabelsEntry]): + labels (Sequence[google.cloud.servicedirectory_v1.types.Namespace.LabelsEntry]): Optional. Resource labels associated with this Namespace. No more than 64 user labels can be associated with a given resource. Label keys diff --git a/google/cloud/servicedirectory_v1/types/registration_service.py b/google/cloud/servicedirectory_v1/types/registration_service.py index c419fba6..94f401cd 100644 --- a/google/cloud/servicedirectory_v1/types/registration_service.py +++ b/google/cloud/servicedirectory_v1/types/registration_service.py @@ -65,7 +65,7 @@ class CreateNamespaceRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - namespace (~.gcs_namespace.Namespace): + namespace (google.cloud.servicedirectory_v1.types.Namespace): Required. A namespace with initial fields set. """ @@ -142,7 +142,7 @@ class ListNamespacesResponse(proto.Message): [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces]. Attributes: - namespaces (Sequence[~.gcs_namespace.Namespace]): + namespaces (Sequence[google.cloud.servicedirectory_v1.types.Namespace]): The list of namespaces. next_page_token (str): Token to retrieve the next page of results, @@ -179,9 +179,9 @@ class UpdateNamespaceRequest(proto.Message): [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1.RegistrationService.UpdateNamespace]. Attributes: - namespace (~.gcs_namespace.Namespace): + namespace (google.cloud.servicedirectory_v1.types.Namespace): Required. The updated namespace. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ @@ -220,7 +220,7 @@ class CreateServiceRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1.types.Service): Required. A service with initial fields set. """ @@ -290,7 +290,7 @@ class ListServicesResponse(proto.Message): [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices]. Attributes: - services (Sequence[~.gcs_service.Service]): + services (Sequence[google.cloud.servicedirectory_v1.types.Service]): The list of services. next_page_token (str): Token to retrieve the next page of results, @@ -329,9 +329,9 @@ class UpdateServiceRequest(proto.Message): [RegistrationService.UpdateService][google.cloud.servicedirectory.v1.RegistrationService.UpdateService]. Attributes: - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1.types.Service): Required. The updated service. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ @@ -369,7 +369,7 @@ class CreateEndpointRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - endpoint (~.gcs_endpoint.Endpoint): + endpoint (google.cloud.servicedirectory_v1.types.Endpoint): Required. A endpoint with initial fields set. """ @@ -444,7 +444,7 @@ class ListEndpointsResponse(proto.Message): [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints]. Attributes: - endpoints (Sequence[~.gcs_endpoint.Endpoint]): + endpoints (Sequence[google.cloud.servicedirectory_v1.types.Endpoint]): The list of endpoints. next_page_token (str): Token to retrieve the next page of results, @@ -482,9 +482,9 @@ class UpdateEndpointRequest(proto.Message): [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.UpdateEndpoint]. Attributes: - endpoint (~.gcs_endpoint.Endpoint): + endpoint (google.cloud.servicedirectory_v1.types.Endpoint): Required. The updated endpoint. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ diff --git a/google/cloud/servicedirectory_v1/types/service.py b/google/cloud/servicedirectory_v1/types/service.py index aaeac5fd..dfcbf942 100644 --- a/google/cloud/servicedirectory_v1/types/service.py +++ b/google/cloud/servicedirectory_v1/types/service.py @@ -36,7 +36,7 @@ class Service(proto.Message): name (str): Immutable. The resource name for the service in the format ``projects/*/locations/*/namespaces/*/services/*`` - annotations (Sequence[~.service.Service.AnnotationsEntry]): + annotations (Sequence[google.cloud.servicedirectory_v1.types.Service.AnnotationsEntry]): Optional. Annotations for the service. This data can be consumed by service clients. Restrictions: @@ -61,7 +61,7 @@ class Service(proto.Message): Note: This field is equivalent to the 'metadata' field in the v1beta1 API. They have the same syntax and read/write to the same location in Service Directory. - endpoints (Sequence[~.endpoint.Endpoint]): + endpoints (Sequence[google.cloud.servicedirectory_v1.types.Endpoint]): Output only. Endpoints associated with this service. Returned on LookupService.Resolve. Control plane clients should use diff --git a/google/cloud/servicedirectory_v1beta1/services/lookup_service/async_client.py b/google/cloud/servicedirectory_v1beta1/services/lookup_service/async_client.py index e2104a9d..b510ded4 100644 --- a/google/cloud/servicedirectory_v1beta1/services/lookup_service/async_client.py +++ b/google/cloud/servicedirectory_v1beta1/services/lookup_service/async_client.py @@ -78,7 +78,36 @@ class LookupServiceAsyncClient: LookupServiceClient.parse_common_location_path ) - from_service_account_file = LookupServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceAsyncClient: The constructed client. + """ + return LookupServiceClient.from_service_account_info.__func__(LookupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceAsyncClient: The constructed client. + """ + return LookupServiceClient.from_service_account_file.__func__(LookupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -156,7 +185,7 @@ async def resolve_service( active developer method. Args: - request (:class:`~.lookup_service.ResolveServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.ResolveServiceRequest`): The request object. The request message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService]. Looks up a service by its name, returns the service and @@ -169,7 +198,7 @@ async def resolve_service( sent along with the request as metadata. Returns: - ~.lookup_service.ResolveServiceResponse: + google.cloud.servicedirectory_v1beta1.types.ResolveServiceResponse: The response message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService]. diff --git a/google/cloud/servicedirectory_v1beta1/services/lookup_service/client.py b/google/cloud/servicedirectory_v1beta1/services/lookup_service/client.py index 90e86633..31afd693 100644 --- a/google/cloud/servicedirectory_v1beta1/services/lookup_service/client.py +++ b/google/cloud/servicedirectory_v1beta1/services/lookup_service/client.py @@ -108,6 +108,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LookupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -120,7 +136,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + LookupServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -250,10 +266,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.LookupServiceTransport]): The + transport (Union[str, LookupServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -289,21 +305,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -346,7 +358,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -365,7 +377,7 @@ def resolve_service( active developer method. Args: - request (:class:`~.lookup_service.ResolveServiceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ResolveServiceRequest): The request object. The request message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService]. Looks up a service by its name, returns the service and @@ -378,7 +390,7 @@ def resolve_service( sent along with the request as metadata. Returns: - ~.lookup_service.ResolveServiceResponse: + google.cloud.servicedirectory_v1beta1.types.ResolveServiceResponse: The response message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService]. diff --git a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/base.py b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/base.py index f42e8a7c..945e24be 100644 --- a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/base.py +++ b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/base.py @@ -69,10 +69,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -80,6 +80,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -89,20 +92,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc.py b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc.py index 6cbb7fbb..15cc988e 100644 --- a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc.py +++ b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc.py @@ -57,6 +57,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -87,6 +88,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -101,72 +106,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -174,17 +167,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -198,7 +182,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc_asyncio.py b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc_asyncio.py index ff8ce54a..a7b71160 100644 --- a/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc_asyncio.py +++ b/google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc_asyncio.py @@ -61,7 +61,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -101,6 +101,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -132,12 +133,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -146,72 +151,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -219,17 +212,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/async_client.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/async_client.py index d15b73b9..1bb47ac6 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/async_client.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/async_client.py @@ -105,7 +105,36 @@ class RegistrationServiceAsyncClient: RegistrationServiceClient.parse_common_location_path ) - from_service_account_file = RegistrationServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceAsyncClient: The constructed client. + """ + return RegistrationServiceClient.from_service_account_info.__func__(RegistrationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceAsyncClient: The constructed client. + """ + return RegistrationServiceClient.from_service_account_file.__func__(RegistrationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -184,19 +213,21 @@ async def create_namespace( r"""Creates a namespace, and returns the new Namespace. Args: - request (:class:`~.registration_service.CreateNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.CreateNamespaceRequest`): The request object. The request message for [RegistrationService.CreateNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateNamespace]. parent (:class:`str`): Required. The resource name of the project and location the namespace will be created in. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (:class:`google.cloud.servicedirectory_v1beta1.types.Namespace`): Required. A namespace with initial fields set. + This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -209,6 +240,7 @@ async def create_namespace( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``namespace_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -220,12 +252,11 @@ async def create_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -282,13 +313,14 @@ async def list_namespaces( r"""Lists all namespaces. Args: - request (:class:`~.registration_service.ListNamespacesRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.ListNamespacesRequest`): The request object. The request message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1beta1.RegistrationService.ListNamespaces]. parent (:class:`str`): Required. The resource name of the project and location whose namespaces we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -300,7 +332,7 @@ async def list_namespaces( sent along with the request as metadata. Returns: - ~.pagers.ListNamespacesAsyncPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListNamespacesAsyncPager: The response message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1beta1.RegistrationService.ListNamespaces]. @@ -364,12 +396,13 @@ async def get_namespace( r"""Gets a namespace. Args: - request (:class:`~.registration_service.GetNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.GetNamespaceRequest`): The request object. The request message for [RegistrationService.GetNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.GetNamespace]. name (:class:`str`): Required. The name of the namespace to retrieve. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -381,12 +414,11 @@ async def get_namespace( sent along with the request as metadata. Returns: - ~.namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -440,17 +472,18 @@ async def update_namespace( r"""Updates a namespace. Args: - request (:class:`~.registration_service.UpdateNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.UpdateNamespaceRequest`): The request object. The request message for [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateNamespace]. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (:class:`google.cloud.servicedirectory_v1beta1.types.Namespace`): Required. The updated namespace. This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -462,12 +495,11 @@ async def update_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -525,12 +557,13 @@ async def delete_namespace( and endpoints in the namespace. Args: - request (:class:`~.registration_service.DeleteNamespaceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.DeleteNamespaceRequest`): The request object. The request message for [RegistrationService.DeleteNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteNamespace]. name (:class:`str`): Required. The name of the namespace to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -592,18 +625,20 @@ async def create_service( r"""Creates a service, and returns the new Service. Args: - request (:class:`~.registration_service.CreateServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.CreateServiceRequest`): The request object. The request message for [RegistrationService.CreateService][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateService]. parent (:class:`str`): Required. The resource name of the namespace this service will belong to. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service (:class:`~.gcs_service.Service`): + service (:class:`google.cloud.servicedirectory_v1beta1.types.Service`): Required. A service with initial fields set. + This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -616,6 +651,7 @@ async def create_service( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -627,11 +663,11 @@ async def create_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -688,13 +724,14 @@ async def list_services( r"""Lists all services belonging to a namespace. Args: - request (:class:`~.registration_service.ListServicesRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.ListServicesRequest`): The request object. The request message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1beta1.RegistrationService.ListServices]. parent (:class:`str`): Required. The resource name of the namespace whose services we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -706,7 +743,7 @@ async def list_services( sent along with the request as metadata. Returns: - ~.pagers.ListServicesAsyncPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListServicesAsyncPager: The response message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1beta1.RegistrationService.ListServices]. @@ -770,7 +807,7 @@ async def get_service( r"""Gets a service. Args: - request (:class:`~.registration_service.GetServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.GetServiceRequest`): The request object. The request message for [RegistrationService.GetService][google.cloud.servicedirectory.v1beta1.RegistrationService.GetService]. This should not be used for looking up a service. @@ -779,6 +816,7 @@ async def get_service( name (:class:`str`): Required. The name of the service to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -790,11 +828,11 @@ async def get_service( sent along with the request as metadata. Returns: - ~.service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -848,17 +886,18 @@ async def update_service( r"""Updates a service. Args: - request (:class:`~.registration_service.UpdateServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.UpdateServiceRequest`): The request object. The request message for [RegistrationService.UpdateService][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateService]. - service (:class:`~.gcs_service.Service`): + service (:class:`google.cloud.servicedirectory_v1beta1.types.Service`): Required. The updated service. This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -870,11 +909,11 @@ async def update_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -932,12 +971,13 @@ async def delete_service( associated with the service. Args: - request (:class:`~.registration_service.DeleteServiceRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.DeleteServiceRequest`): The request object. The request message for [RegistrationService.DeleteService][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteService]. name (:class:`str`): Required. The name of the service to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -999,18 +1039,20 @@ async def create_endpoint( r"""Creates a endpoint, and returns the new Endpoint. Args: - request (:class:`~.registration_service.CreateEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.CreateEndpointRequest`): The request object. The request message for [RegistrationService.CreateEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateEndpoint]. parent (:class:`str`): Required. The resource name of the service that this endpoint provides. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (:class:`google.cloud.servicedirectory_v1beta1.types.Endpoint`): Required. A endpoint with initial fields set. + This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1023,6 +1065,7 @@ async def create_endpoint( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``endpoint_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1034,10 +1077,10 @@ async def create_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1094,13 +1137,14 @@ async def list_endpoints( r"""Lists all endpoints. Args: - request (:class:`~.registration_service.ListEndpointsRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.ListEndpointsRequest`): The request object. The request message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1beta1.RegistrationService.ListEndpoints]. parent (:class:`str`): Required. The resource name of the service whose endpoints we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1112,7 +1156,7 @@ async def list_endpoints( sent along with the request as metadata. Returns: - ~.pagers.ListEndpointsAsyncPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListEndpointsAsyncPager: The response message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1beta1.RegistrationService.ListEndpoints]. @@ -1176,7 +1220,7 @@ async def get_endpoint( r"""Gets a endpoint. Args: - request (:class:`~.registration_service.GetEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.GetEndpointRequest`): The request object. The request message for [RegistrationService.GetEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.GetEndpoint]. This should not be used to lookup endpoints at runtime. @@ -1184,6 +1228,7 @@ async def get_endpoint( name (:class:`str`): Required. The name of the endpoint to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1195,10 +1240,10 @@ async def get_endpoint( sent along with the request as metadata. Returns: - ~.endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1252,17 +1297,18 @@ async def update_endpoint( r"""Updates a endpoint. Args: - request (:class:`~.registration_service.UpdateEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.UpdateEndpointRequest`): The request object. The request message for [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateEndpoint]. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (:class:`google.cloud.servicedirectory_v1beta1.types.Endpoint`): Required. The updated endpoint. This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1274,10 +1320,10 @@ async def update_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1334,12 +1380,13 @@ async def delete_endpoint( r"""Deletes a endpoint. Args: - request (:class:`~.registration_service.DeleteEndpointRequest`): + request (:class:`google.cloud.servicedirectory_v1beta1.types.DeleteEndpointRequest`): The request object. The request message for [RegistrationService.DeleteEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteEndpoint]. name (:class:`str`): Required. The name of the endpoint to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1399,7 +1446,7 @@ async def get_iam_policy( service only). Args: - request (:class:`~.iam_policy.GetIamPolicyRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.GetIamPolicyRequest`): The request object. Request message for `GetIamPolicy` method. @@ -1410,72 +1457,62 @@ async def get_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. @@ -1517,7 +1554,7 @@ async def set_iam_policy( service only). Args: - request (:class:`~.iam_policy.SetIamPolicyRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.SetIamPolicyRequest`): The request object. Request message for `SetIamPolicy` method. @@ -1528,72 +1565,62 @@ async def set_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. @@ -1635,7 +1662,7 @@ async def test_iam_permissions( service only). Args: - request (:class:`~.iam_policy.TestIamPermissionsRequest`): + request (:class:`google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest`): The request object. Request message for `TestIamPermissions` method. @@ -1646,8 +1673,8 @@ async def test_iam_permissions( sent along with the request as metadata. Returns: - ~.iam_policy.TestIamPermissionsResponse: - Response message for ``TestIamPermissions`` method. + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/client.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/client.py index c96f1218..f275047a 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/client.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/client.py @@ -137,6 +137,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RegistrationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -149,7 +165,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + RegistrationServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -295,10 +311,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.RegistrationServiceTransport]): The + transport (Union[str, RegistrationServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -334,21 +350,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -391,7 +403,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -410,23 +422,25 @@ def create_namespace( r"""Creates a namespace, and returns the new Namespace. Args: - request (:class:`~.registration_service.CreateNamespaceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.CreateNamespaceRequest): The request object. The request message for [RegistrationService.CreateNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateNamespace]. - parent (:class:`str`): + parent (str): Required. The resource name of the project and location the namespace will be created in. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (google.cloud.servicedirectory_v1beta1.types.Namespace): Required. A namespace with initial fields set. + This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - namespace_id (:class:`str`): + namespace_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -435,6 +449,7 @@ def create_namespace( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``namespace_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -446,12 +461,11 @@ def create_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -509,13 +523,14 @@ def list_namespaces( r"""Lists all namespaces. Args: - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListNamespacesRequest): The request object. The request message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1beta1.RegistrationService.ListNamespaces]. - parent (:class:`str`): + parent (str): Required. The resource name of the project and location whose namespaces we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -527,7 +542,7 @@ def list_namespaces( sent along with the request as metadata. Returns: - ~.pagers.ListNamespacesPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListNamespacesPager: The response message for [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1beta1.RegistrationService.ListNamespaces]. @@ -592,12 +607,13 @@ def get_namespace( r"""Gets a namespace. Args: - request (:class:`~.registration_service.GetNamespaceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.GetNamespaceRequest): The request object. The request message for [RegistrationService.GetNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.GetNamespace]. - name (:class:`str`): + name (str): Required. The name of the namespace to retrieve. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -609,12 +625,11 @@ def get_namespace( sent along with the request as metadata. Returns: - ~.namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -669,17 +684,18 @@ def update_namespace( r"""Updates a namespace. Args: - request (:class:`~.registration_service.UpdateNamespaceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.UpdateNamespaceRequest): The request object. The request message for [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateNamespace]. - namespace (:class:`~.gcs_namespace.Namespace`): + namespace (google.cloud.servicedirectory_v1beta1.types.Namespace): Required. The updated namespace. This corresponds to the ``namespace`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -691,12 +707,11 @@ def update_namespace( sent along with the request as metadata. Returns: - ~.gcs_namespace.Namespace: - A container for - [services][google.cloud.servicedirectory.v1beta1.Service]. - Namespaces allow administrators to group services - together and define permissions for a collection of - services. + google.cloud.servicedirectory_v1beta1.types.Namespace: + A container for [services][google.cloud.servicedirectory.v1beta1.Service]. + Namespaces allow administrators to group services + together and define permissions for a collection of + services. """ # Create or coerce a protobuf request object. @@ -755,12 +770,13 @@ def delete_namespace( and endpoints in the namespace. Args: - request (:class:`~.registration_service.DeleteNamespaceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.DeleteNamespaceRequest): The request object. The request message for [RegistrationService.DeleteNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteNamespace]. - name (:class:`str`): + name (str): Required. The name of the namespace to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -823,22 +839,24 @@ def create_service( r"""Creates a service, and returns the new Service. Args: - request (:class:`~.registration_service.CreateServiceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.CreateServiceRequest): The request object. The request message for [RegistrationService.CreateService][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateService]. - parent (:class:`str`): + parent (str): Required. The resource name of the namespace this service will belong to. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service (:class:`~.gcs_service.Service`): + service (google.cloud.servicedirectory_v1beta1.types.Service): Required. A service with initial fields set. + This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - service_id (:class:`str`): + service_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -847,6 +865,7 @@ def create_service( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -858,11 +877,11 @@ def create_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -920,13 +939,14 @@ def list_services( r"""Lists all services belonging to a namespace. Args: - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListServicesRequest): The request object. The request message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1beta1.RegistrationService.ListServices]. - parent (:class:`str`): + parent (str): Required. The resource name of the namespace whose services we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -938,7 +958,7 @@ def list_services( sent along with the request as metadata. Returns: - ~.pagers.ListServicesPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListServicesPager: The response message for [RegistrationService.ListServices][google.cloud.servicedirectory.v1beta1.RegistrationService.ListServices]. @@ -1003,15 +1023,16 @@ def get_service( r"""Gets a service. Args: - request (:class:`~.registration_service.GetServiceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.GetServiceRequest): The request object. The request message for [RegistrationService.GetService][google.cloud.servicedirectory.v1beta1.RegistrationService.GetService]. This should not be used for looking up a service. Insead, use the `resolve` method as it will contain all endpoints and associated metadata. - name (:class:`str`): + name (str): Required. The name of the service to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1023,11 +1044,11 @@ def get_service( sent along with the request as metadata. Returns: - ~.service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -1082,17 +1103,18 @@ def update_service( r"""Updates a service. Args: - request (:class:`~.registration_service.UpdateServiceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.UpdateServiceRequest): The request object. The request message for [RegistrationService.UpdateService][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateService]. - service (:class:`~.gcs_service.Service`): + service (google.cloud.servicedirectory_v1beta1.types.Service): Required. The updated service. This corresponds to the ``service`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1104,11 +1126,11 @@ def update_service( sent along with the request as metadata. Returns: - ~.gcs_service.Service: - An individual service. A service contains a name and - optional metadata. A service must exist before - [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] - can be added to it. + google.cloud.servicedirectory_v1beta1.types.Service: + An individual service. A service contains a name and optional metadata. + A service must exist before + [endpoints][google.cloud.servicedirectory.v1beta1.Endpoint] + can be added to it. """ # Create or coerce a protobuf request object. @@ -1167,12 +1189,13 @@ def delete_service( associated with the service. Args: - request (:class:`~.registration_service.DeleteServiceRequest`): + request (google.cloud.servicedirectory_v1beta1.types.DeleteServiceRequest): The request object. The request message for [RegistrationService.DeleteService][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteService]. - name (:class:`str`): + name (str): Required. The name of the service to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1235,22 +1258,24 @@ def create_endpoint( r"""Creates a endpoint, and returns the new Endpoint. Args: - request (:class:`~.registration_service.CreateEndpointRequest`): + request (google.cloud.servicedirectory_v1beta1.types.CreateEndpointRequest): The request object. The request message for [RegistrationService.CreateEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.CreateEndpoint]. - parent (:class:`str`): + parent (str): Required. The resource name of the service that this endpoint provides. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (google.cloud.servicedirectory_v1beta1.types.Endpoint): Required. A endpoint with initial fields set. + This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - endpoint_id (:class:`str`): + endpoint_id (str): Required. The Resource ID must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression @@ -1259,6 +1284,7 @@ def create_endpoint( following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + This corresponds to the ``endpoint_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1270,10 +1296,10 @@ def create_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1331,13 +1357,14 @@ def list_endpoints( r"""Lists all endpoints. Args: - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListEndpointsRequest): The request object. The request message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1beta1.RegistrationService.ListEndpoints]. - parent (:class:`str`): + parent (str): Required. The resource name of the service whose endpoints we'd like to list. + This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1349,7 +1376,7 @@ def list_endpoints( sent along with the request as metadata. Returns: - ~.pagers.ListEndpointsPager: + google.cloud.servicedirectory_v1beta1.services.registration_service.pagers.ListEndpointsPager: The response message for [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1beta1.RegistrationService.ListEndpoints]. @@ -1414,14 +1441,15 @@ def get_endpoint( r"""Gets a endpoint. Args: - request (:class:`~.registration_service.GetEndpointRequest`): + request (google.cloud.servicedirectory_v1beta1.types.GetEndpointRequest): The request object. The request message for [RegistrationService.GetEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.GetEndpoint]. This should not be used to lookup endpoints at runtime. Instead, use the `resolve` method. - name (:class:`str`): + name (str): Required. The name of the endpoint to get. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1433,10 +1461,10 @@ def get_endpoint( sent along with the request as metadata. Returns: - ~.endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1491,17 +1519,18 @@ def update_endpoint( r"""Updates a endpoint. Args: - request (:class:`~.registration_service.UpdateEndpointRequest`): + request (google.cloud.servicedirectory_v1beta1.types.UpdateEndpointRequest): The request object. The request message for [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateEndpoint]. - endpoint (:class:`~.gcs_endpoint.Endpoint`): + endpoint (google.cloud.servicedirectory_v1beta1.types.Endpoint): Required. The updated endpoint. This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - update_mask (:class:`~.field_mask.FieldMask`): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. + This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1513,10 +1542,10 @@ def update_endpoint( sent along with the request as metadata. Returns: - ~.gcs_endpoint.Endpoint: + google.cloud.servicedirectory_v1beta1.types.Endpoint: An individual endpoint that provides a - [service][google.cloud.servicedirectory.v1beta1.Service]. - The service must already exist to create an endpoint. + [service][google.cloud.servicedirectory.v1beta1.Service]. + The service must already exist to create an endpoint. """ # Create or coerce a protobuf request object. @@ -1574,12 +1603,13 @@ def delete_endpoint( r"""Deletes a endpoint. Args: - request (:class:`~.registration_service.DeleteEndpointRequest`): + request (google.cloud.servicedirectory_v1beta1.types.DeleteEndpointRequest): The request object. The request message for [RegistrationService.DeleteEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.DeleteEndpoint]. - name (:class:`str`): + name (str): Required. The name of the endpoint to delete. + This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -1640,7 +1670,7 @@ def get_iam_policy( service only). Args: - request (:class:`~.iam_policy.GetIamPolicyRequest`): + request (google.iam.v1.iam_policy_pb2.GetIamPolicyRequest): The request object. Request message for `GetIamPolicy` method. @@ -1651,80 +1681,73 @@ def get_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.GetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.GetIamPolicyRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1754,7 +1777,7 @@ def set_iam_policy( service only). Args: - request (:class:`~.iam_policy.SetIamPolicyRequest`): + request (google.iam.v1.iam_policy_pb2.SetIamPolicyRequest): The request object. Request message for `SetIamPolicy` method. @@ -1765,80 +1788,73 @@ def set_iam_policy( sent along with the request as metadata. Returns: - ~.policy.Policy: - Defines an Identity and Access Management (IAM) policy. - It is used to specify access control policies for Cloud - Platform resources. - - A ``Policy`` is a collection of ``bindings``. A - ``binding`` binds one or more ``members`` to a single - ``role``. Members can be user accounts, service - accounts, Google groups, and domains (such as G Suite). - A ``role`` is a named list of permissions (defined by - IAM or configured by users). A ``binding`` can - optionally specify a ``condition``, which is a logic - expression that further constrains the role binding - based on attributes about the request and/or target - resource. - - **JSON Example** - - :: - - { - "bindings": [ - { - "role": "roles/resourcemanager.organizationAdmin", - "members": [ - "user:mike@example.com", - "group:admins@example.com", - "domain:google.com", - "serviceAccount:my-project-id@appspot.gserviceaccount.com" - ] - }, - { - "role": "roles/resourcemanager.organizationViewer", - "members": ["user:eve@example.com"], - "condition": { - "title": "expirable access", - "description": "Does not grant access after Sep 2020", - "expression": "request.time < - timestamp('2020-10-01T00:00:00.000Z')", - } - } - ] - } - - **YAML Example** - - :: - - bindings: - - members: - - user:mike@example.com - - group:admins@example.com - - domain:google.com - - serviceAccount:my-project-id@appspot.gserviceaccount.com - role: roles/resourcemanager.organizationAdmin - - members: - - user:eve@example.com - role: roles/resourcemanager.organizationViewer - condition: - title: expirable access - description: Does not grant access after Sep 2020 - expression: request.time < timestamp('2020-10-01T00:00:00.000Z') - - For a description of IAM and its features, see the `IAM - developer's - guide `__. + google.iam.v1.policy_pb2.Policy: + Defines an Identity and Access Management (IAM) policy. It is used to + specify access control policies for Cloud Platform + resources. + + A Policy is a collection of bindings. A binding binds + one or more members to a single role. Members can be + user accounts, service accounts, Google groups, and + domains (such as G Suite). A role is a named list of + permissions (defined by IAM or configured by users). + A binding can optionally specify a condition, which + is a logic expression that further constrains the + role binding based on attributes about the request + and/or target resource. + + **JSON Example** + + { + "bindings": [ + { + "role": + "roles/resourcemanager.organizationAdmin", + "members": [ "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ] + + }, { "role": + "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { "title": "expirable access", + "description": "Does not grant access after + Sep 2020", "expression": "request.time < + timestamp('2020-10-01T00:00:00.000Z')", } } + + ] + + } + + **YAML Example** + + bindings: - members: - user:\ mike@example.com - + group:\ admins@example.com - domain:google.com - + serviceAccount:\ my-project-id@appspot.gserviceaccount.com + role: roles/resourcemanager.organizationAdmin - + members: - user:\ eve@example.com role: + roles/resourcemanager.organizationViewer + condition: title: expirable access description: + Does not grant access after Sep 2020 expression: + request.time < + timestamp('2020-10-01T00:00:00.000Z') + + For a description of IAM and its features, see the + [IAM developer's + guide](\ https://cloud.google.com/iam/docs). """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.SetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.SetIamPolicyRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1868,7 +1884,7 @@ def test_iam_permissions( service only). Args: - request (:class:`~.iam_policy.TestIamPermissionsRequest`): + request (google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest): The request object. Request message for `TestIamPermissions` method. @@ -1879,15 +1895,18 @@ def test_iam_permissions( sent along with the request as metadata. Returns: - ~.iam_policy.TestIamPermissionsResponse: - Response message for ``TestIamPermissions`` method. + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. - # The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. request = iam_policy.TestIamPermissionsRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy.TestIamPermissionsRequest() # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/pagers.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/pagers.py index 0ff0bca6..974003d8 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/pagers.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/pagers.py @@ -15,7 +15,16 @@ # limitations under the License. # -from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple +from typing import ( + Any, + AsyncIterable, + Awaitable, + Callable, + Iterable, + Sequence, + Tuple, + Optional, +) from google.cloud.servicedirectory_v1beta1.types import endpoint from google.cloud.servicedirectory_v1beta1.types import namespace @@ -27,7 +36,7 @@ class ListNamespacesPager: """A pager for iterating through ``list_namespaces`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListNamespacesResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse` object, and provides an ``__iter__`` method to iterate through its ``namespaces`` field. @@ -36,7 +45,7 @@ class ListNamespacesPager: through the ``namespaces`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListNamespacesResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -54,9 +63,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListNamespacesRequest): The initial request object. - response (:class:`~.registration_service.ListNamespacesResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -89,7 +98,7 @@ class ListNamespacesAsyncPager: """A pager for iterating through ``list_namespaces`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListNamespacesResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse` object, and provides an ``__aiter__`` method to iterate through its ``namespaces`` field. @@ -98,7 +107,7 @@ class ListNamespacesAsyncPager: through the ``namespaces`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListNamespacesResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -116,9 +125,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListNamespacesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListNamespacesRequest): The initial request object. - response (:class:`~.registration_service.ListNamespacesResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListNamespacesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -155,7 +164,7 @@ class ListServicesPager: """A pager for iterating through ``list_services`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListServicesResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListServicesResponse` object, and provides an ``__iter__`` method to iterate through its ``services`` field. @@ -164,7 +173,7 @@ class ListServicesPager: through the ``services`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListServicesResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListServicesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -182,9 +191,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListServicesRequest): The initial request object. - response (:class:`~.registration_service.ListServicesResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListServicesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -217,7 +226,7 @@ class ListServicesAsyncPager: """A pager for iterating through ``list_services`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListServicesResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListServicesResponse` object, and provides an ``__aiter__`` method to iterate through its ``services`` field. @@ -226,7 +235,7 @@ class ListServicesAsyncPager: through the ``services`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListServicesResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListServicesResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -244,9 +253,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListServicesRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListServicesRequest): The initial request object. - response (:class:`~.registration_service.ListServicesResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListServicesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -283,7 +292,7 @@ class ListEndpointsPager: """A pager for iterating through ``list_endpoints`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListEndpointsResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse` object, and provides an ``__iter__`` method to iterate through its ``endpoints`` field. @@ -292,7 +301,7 @@ class ListEndpointsPager: through the ``endpoints`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListEndpointsResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -310,9 +319,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListEndpointsRequest): The initial request object. - response (:class:`~.registration_service.ListEndpointsResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -345,7 +354,7 @@ class ListEndpointsAsyncPager: """A pager for iterating through ``list_endpoints`` requests. This class thinly wraps an initial - :class:`~.registration_service.ListEndpointsResponse` object, and + :class:`google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse` object, and provides an ``__aiter__`` method to iterate through its ``endpoints`` field. @@ -354,7 +363,7 @@ class ListEndpointsAsyncPager: through the ``endpoints`` field on the corresponding responses. - All the usual :class:`~.registration_service.ListEndpointsResponse` + All the usual :class:`google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse` attributes are available on the pager. If multiple requests are made, only the most recent response is retained, and thus used for attribute lookup. """ @@ -372,9 +381,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.registration_service.ListEndpointsRequest`): + request (google.cloud.servicedirectory_v1beta1.types.ListEndpointsRequest): The initial request object. - response (:class:`~.registration_service.ListEndpointsResponse`): + response (google.cloud.servicedirectory_v1beta1.types.ListEndpointsResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/base.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/base.py index 117efff6..97a06ae5 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/base.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/base.py @@ -78,10 +78,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -89,6 +89,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -98,20 +101,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc.py index 6f0b0e23..b69133c7 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc.py @@ -81,6 +81,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -111,6 +112,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -125,72 +130,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -198,17 +191,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -222,7 +206,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc_asyncio.py b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc_asyncio.py index fa04dc14..06048cf4 100644 --- a/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc_asyncio.py +++ b/google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc_asyncio.py @@ -85,7 +85,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -125,6 +125,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -156,12 +157,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -170,72 +175,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -243,17 +236,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/google/cloud/servicedirectory_v1beta1/types/__init__.py b/google/cloud/servicedirectory_v1beta1/types/__init__.py index 505b0c76..6ede60ca 100644 --- a/google/cloud/servicedirectory_v1beta1/types/__init__.py +++ b/google/cloud/servicedirectory_v1beta1/types/__init__.py @@ -16,55 +16,55 @@ # from .endpoint import Endpoint -from .service import Service from .lookup_service import ( ResolveServiceRequest, ResolveServiceResponse, ) from .namespace import Namespace from .registration_service import ( + CreateEndpointRequest, CreateNamespaceRequest, - ListNamespacesRequest, - ListNamespacesResponse, - GetNamespaceRequest, - UpdateNamespaceRequest, - DeleteNamespaceRequest, CreateServiceRequest, - ListServicesRequest, - ListServicesResponse, - GetServiceRequest, - UpdateServiceRequest, + DeleteEndpointRequest, + DeleteNamespaceRequest, DeleteServiceRequest, - CreateEndpointRequest, + GetEndpointRequest, + GetNamespaceRequest, + GetServiceRequest, ListEndpointsRequest, ListEndpointsResponse, - GetEndpointRequest, + ListNamespacesRequest, + ListNamespacesResponse, + ListServicesRequest, + ListServicesResponse, UpdateEndpointRequest, - DeleteEndpointRequest, + UpdateNamespaceRequest, + UpdateServiceRequest, ) +from .service import Service __all__ = ( "Endpoint", - "Service", "ResolveServiceRequest", "ResolveServiceResponse", "Namespace", + "CreateEndpointRequest", "CreateNamespaceRequest", - "ListNamespacesRequest", - "ListNamespacesResponse", - "GetNamespaceRequest", - "UpdateNamespaceRequest", - "DeleteNamespaceRequest", "CreateServiceRequest", - "ListServicesRequest", - "ListServicesResponse", - "GetServiceRequest", - "UpdateServiceRequest", + "DeleteEndpointRequest", + "DeleteNamespaceRequest", "DeleteServiceRequest", - "CreateEndpointRequest", + "GetEndpointRequest", + "GetNamespaceRequest", + "GetServiceRequest", "ListEndpointsRequest", "ListEndpointsResponse", - "GetEndpointRequest", + "ListNamespacesRequest", + "ListNamespacesResponse", + "ListServicesRequest", + "ListServicesResponse", "UpdateEndpointRequest", - "DeleteEndpointRequest", + "UpdateNamespaceRequest", + "UpdateServiceRequest", + "Service", ) diff --git a/google/cloud/servicedirectory_v1beta1/types/endpoint.py b/google/cloud/servicedirectory_v1beta1/types/endpoint.py index a5039984..3b9ff35a 100644 --- a/google/cloud/servicedirectory_v1beta1/types/endpoint.py +++ b/google/cloud/servicedirectory_v1beta1/types/endpoint.py @@ -40,7 +40,7 @@ class Endpoint(proto.Message): port (int): Optional. Service Directory will reject values outside of [0, 65535]. - metadata (Sequence[~.endpoint.Endpoint.MetadataEntry]): + metadata (Sequence[google.cloud.servicedirectory_v1beta1.types.Endpoint.MetadataEntry]): Optional. Metadata for the endpoint. This data can be consumed by service clients. The entire metadata dictionary may contain up to 512 diff --git a/google/cloud/servicedirectory_v1beta1/types/lookup_service.py b/google/cloud/servicedirectory_v1beta1/types/lookup_service.py index bbf01ab3..a58f36b6 100644 --- a/google/cloud/servicedirectory_v1beta1/types/lookup_service.py +++ b/google/cloud/servicedirectory_v1beta1/types/lookup_service.py @@ -74,7 +74,7 @@ class ResolveServiceResponse(proto.Message): [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService]. Attributes: - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1beta1.types.Service): """ diff --git a/google/cloud/servicedirectory_v1beta1/types/namespace.py b/google/cloud/servicedirectory_v1beta1/types/namespace.py index bed25613..de8a874a 100644 --- a/google/cloud/servicedirectory_v1beta1/types/namespace.py +++ b/google/cloud/servicedirectory_v1beta1/types/namespace.py @@ -33,7 +33,7 @@ class Namespace(proto.Message): name (str): Immutable. The resource name for the namespace in the format ``projects/*/locations/*/namespaces/*`` - labels (Sequence[~.namespace.Namespace.LabelsEntry]): + labels (Sequence[google.cloud.servicedirectory_v1beta1.types.Namespace.LabelsEntry]): Optional. Resource labels associated with this Namespace. No more than 64 user labels can be associated with a given resource. Label keys diff --git a/google/cloud/servicedirectory_v1beta1/types/registration_service.py b/google/cloud/servicedirectory_v1beta1/types/registration_service.py index daa67d4b..1a5f608e 100644 --- a/google/cloud/servicedirectory_v1beta1/types/registration_service.py +++ b/google/cloud/servicedirectory_v1beta1/types/registration_service.py @@ -65,7 +65,7 @@ class CreateNamespaceRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - namespace (~.gcs_namespace.Namespace): + namespace (google.cloud.servicedirectory_v1beta1.types.Namespace): Required. A namespace with initial fields set. """ @@ -142,7 +142,7 @@ class ListNamespacesResponse(proto.Message): [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1beta1.RegistrationService.ListNamespaces]. Attributes: - namespaces (Sequence[~.gcs_namespace.Namespace]): + namespaces (Sequence[google.cloud.servicedirectory_v1beta1.types.Namespace]): The list of namespaces. next_page_token (str): Token to retrieve the next page of results, @@ -179,9 +179,9 @@ class UpdateNamespaceRequest(proto.Message): [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateNamespace]. Attributes: - namespace (~.gcs_namespace.Namespace): + namespace (google.cloud.servicedirectory_v1beta1.types.Namespace): Required. The updated namespace. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ @@ -220,7 +220,7 @@ class CreateServiceRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1beta1.types.Service): Required. A service with initial fields set. """ @@ -290,7 +290,7 @@ class ListServicesResponse(proto.Message): [RegistrationService.ListServices][google.cloud.servicedirectory.v1beta1.RegistrationService.ListServices]. Attributes: - services (Sequence[~.gcs_service.Service]): + services (Sequence[google.cloud.servicedirectory_v1beta1.types.Service]): The list of services. next_page_token (str): Token to retrieve the next page of results, @@ -329,9 +329,9 @@ class UpdateServiceRequest(proto.Message): [RegistrationService.UpdateService][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateService]. Attributes: - service (~.gcs_service.Service): + service (google.cloud.servicedirectory_v1beta1.types.Service): Required. The updated service. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ @@ -369,7 +369,7 @@ class CreateEndpointRequest(proto.Message): character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. - endpoint (~.gcs_endpoint.Endpoint): + endpoint (google.cloud.servicedirectory_v1beta1.types.Endpoint): Required. A endpoint with initial fields set. """ @@ -444,7 +444,7 @@ class ListEndpointsResponse(proto.Message): [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1beta1.RegistrationService.ListEndpoints]. Attributes: - endpoints (Sequence[~.gcs_endpoint.Endpoint]): + endpoints (Sequence[google.cloud.servicedirectory_v1beta1.types.Endpoint]): The list of endpoints. next_page_token (str): Token to retrieve the next page of results, @@ -482,9 +482,9 @@ class UpdateEndpointRequest(proto.Message): [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1beta1.RegistrationService.UpdateEndpoint]. Attributes: - endpoint (~.gcs_endpoint.Endpoint): + endpoint (google.cloud.servicedirectory_v1beta1.types.Endpoint): Required. The updated endpoint. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. List of fields to be updated in this request. """ diff --git a/google/cloud/servicedirectory_v1beta1/types/service.py b/google/cloud/servicedirectory_v1beta1/types/service.py index e1f15191..1a2fe2af 100644 --- a/google/cloud/servicedirectory_v1beta1/types/service.py +++ b/google/cloud/servicedirectory_v1beta1/types/service.py @@ -36,14 +36,14 @@ class Service(proto.Message): name (str): Immutable. The resource name for the service in the format ``projects/*/locations/*/namespaces/*/services/*`` - metadata (Sequence[~.service.Service.MetadataEntry]): + metadata (Sequence[google.cloud.servicedirectory_v1beta1.types.Service.MetadataEntry]): Optional. Metadata for the service. This data can be consumed by service clients. The entire metadata dictionary may contain up to 2000 characters, spread across all key-value pairs. Metadata that goes beyond any these limits will be rejected. - endpoints (Sequence[~.endpoint.Endpoint]): + endpoints (Sequence[google.cloud.servicedirectory_v1beta1.types.Endpoint]): Output only. Endpoints associated with this service. Returned on LookupService.Resolve. Control plane clients should use diff --git a/noxfile.py b/noxfile.py index 8004482e..8e9b9413 100644 --- a/noxfile.py +++ b/noxfile.py @@ -18,6 +18,7 @@ from __future__ import absolute_import import os +import pathlib import shutil import nox @@ -30,6 +31,22 @@ SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +# 'docfx' is excluded since it only needs to run in 'docs-presubmit' +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint(session): @@ -70,17 +87,21 @@ def lint_setup_py(session): def default(session): # Install all test dependencies, then install this package in-place. - session.install("asyncmock", "pytest-asyncio") - session.install( - "mock", "pytest", "pytest-cov", + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) - session.install("-e", ".") + session.install("asyncmock", "pytest-asyncio", "-c", constraints_path) + + session.install("mock", "pytest", "pytest-cov", "-c", constraints_path) + + session.install("-e", ".", "-c", constraints_path) # Run py.test against the unit tests. session.run( "py.test", "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=google/cloud", "--cov=tests/unit", "--cov-append", @@ -101,6 +122,9 @@ def unit(session): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def system(session): """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") @@ -110,6 +134,9 @@ def system(session): # Sanity check: Only run tests if the environment variable is set. if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): session.skip("Credentials must be set via environment variable") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") system_test_exists = os.path.exists(system_test_path) system_test_folder_exists = os.path.exists(system_test_folder_path) @@ -122,16 +149,26 @@ def system(session): # Install all test dependencies, then install this package into the # virtualenv's dist-packages. - session.install( - "mock", "pytest", "google-cloud-testutils", - ) - session.install("-e", ".") + session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path) + session.install("-e", ".", "-c", constraints_path) # Run py.test against the system tests. if system_test_exists: - session.run("py.test", "--quiet", system_test_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) if system_test_folder_exists: - session.run("py.test", "--quiet", system_test_folder_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) diff --git a/renovate.json b/renovate.json index 4fa94931..f08bc22c 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,6 @@ { "extends": [ "config:base", ":preserveSemverRanges" - ] + ], + "ignorePaths": [".pre-commit-config.yaml"] } diff --git a/synth.metadata b/synth.metadata index 2d86b6b1..461ac868 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,30 +3,30 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-service-directory.git", - "sha": "27a4dab1a6fa8ba5120498f3f586ed7203c03b1e" + "remote": "git@github.com:googleapis/python-service-directory", + "sha": "351ce96c54fd3489ba9923b7feeef38df745390a" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "f967ea0c0437a269515665ff9dbb69fcf134ddd9", - "internalRef": "347681363" + "sha": "a1af63efb82f54428ab35ea76869d9cd57ca52b8", + "internalRef": "364635275" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "41a4e56982620d3edcf110d76f4fcdfdec471ac8" + "sha": "86ed43d4f56e6404d068e62e497029018879c771" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "41a4e56982620d3edcf110d76f4fcdfdec471ac8" + "sha": "86ed43d4f56e6404d068e62e497029018879c771" } } ], @@ -49,134 +49,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/multiprocessing.rst", - "docs/servicedirectory_v1/services.rst", - "docs/servicedirectory_v1/types.rst", - "docs/servicedirectory_v1beta1/services.rst", - "docs/servicedirectory_v1beta1/types.rst", - "google/cloud/servicedirectory/__init__.py", - "google/cloud/servicedirectory/py.typed", - "google/cloud/servicedirectory_v1/__init__.py", - "google/cloud/servicedirectory_v1/py.typed", - "google/cloud/servicedirectory_v1/services/__init__.py", - "google/cloud/servicedirectory_v1/services/lookup_service/__init__.py", - "google/cloud/servicedirectory_v1/services/lookup_service/async_client.py", - "google/cloud/servicedirectory_v1/services/lookup_service/client.py", - "google/cloud/servicedirectory_v1/services/lookup_service/transports/__init__.py", - "google/cloud/servicedirectory_v1/services/lookup_service/transports/base.py", - "google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc.py", - "google/cloud/servicedirectory_v1/services/lookup_service/transports/grpc_asyncio.py", - "google/cloud/servicedirectory_v1/services/registration_service/__init__.py", - "google/cloud/servicedirectory_v1/services/registration_service/async_client.py", - "google/cloud/servicedirectory_v1/services/registration_service/client.py", - "google/cloud/servicedirectory_v1/services/registration_service/pagers.py", - "google/cloud/servicedirectory_v1/services/registration_service/transports/__init__.py", - "google/cloud/servicedirectory_v1/services/registration_service/transports/base.py", - "google/cloud/servicedirectory_v1/services/registration_service/transports/grpc.py", - "google/cloud/servicedirectory_v1/services/registration_service/transports/grpc_asyncio.py", - "google/cloud/servicedirectory_v1/types/__init__.py", - "google/cloud/servicedirectory_v1/types/endpoint.py", - "google/cloud/servicedirectory_v1/types/lookup_service.py", - "google/cloud/servicedirectory_v1/types/namespace.py", - "google/cloud/servicedirectory_v1/types/registration_service.py", - "google/cloud/servicedirectory_v1/types/service.py", - "google/cloud/servicedirectory_v1beta1/__init__.py", - "google/cloud/servicedirectory_v1beta1/py.typed", - "google/cloud/servicedirectory_v1beta1/services/__init__.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/__init__.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/async_client.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/client.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/__init__.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/base.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc.py", - "google/cloud/servicedirectory_v1beta1/services/lookup_service/transports/grpc_asyncio.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/__init__.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/async_client.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/client.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/pagers.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/transports/__init__.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/transports/base.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc.py", - "google/cloud/servicedirectory_v1beta1/services/registration_service/transports/grpc_asyncio.py", - "google/cloud/servicedirectory_v1beta1/types/__init__.py", - "google/cloud/servicedirectory_v1beta1/types/endpoint.py", - "google/cloud/servicedirectory_v1beta1/types/lookup_service.py", - "google/cloud/servicedirectory_v1beta1/types/namespace.py", - "google/cloud/servicedirectory_v1beta1/types/registration_service.py", - "google/cloud/servicedirectory_v1beta1/types/service.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "scripts/decrypt-secrets.sh", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/servicedirectory_v1/__init__.py", - "tests/unit/gapic/servicedirectory_v1/test_lookup_service.py", - "tests/unit/gapic/servicedirectory_v1/test_registration_service.py", - "tests/unit/gapic/servicedirectory_v1beta1/__init__.py", - "tests/unit/gapic/servicedirectory_v1beta1/test_lookup_service.py", - "tests/unit/gapic/servicedirectory_v1beta1/test_registration_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/servicedirectory_v1/__init__.py b/tests/unit/gapic/servicedirectory_v1/__init__.py index 8b137891..42ffdf2b 100644 --- a/tests/unit/gapic/servicedirectory_v1/__init__.py +++ b/tests/unit/gapic/servicedirectory_v1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# 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. +# diff --git a/tests/unit/gapic/servicedirectory_v1/test_lookup_service.py b/tests/unit/gapic/servicedirectory_v1/test_lookup_service.py index b910a744..9d39a470 100644 --- a/tests/unit/gapic/servicedirectory_v1/test_lookup_service.py +++ b/tests/unit/gapic/servicedirectory_v1/test_lookup_service.py @@ -87,7 +87,24 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [LookupServiceClient, LookupServiceAsyncClient] + "client_class", [LookupServiceClient, LookupServiceAsyncClient,] +) +def test_lookup_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "servicedirectory.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", [LookupServiceClient, LookupServiceAsyncClient,] ) def test_lookup_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -97,16 +114,21 @@ def test_lookup_service_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "servicedirectory.googleapis.com:443" def test_lookup_service_client_get_transport_class(): transport = LookupServiceClient.get_transport_class() - assert transport == transports.LookupServiceGrpcTransport + available_transports = [ + transports.LookupServiceGrpcTransport, + ] + assert transport in available_transports transport = LookupServiceClient.get_transport_class("grpc") assert transport == transports.LookupServiceGrpcTransport @@ -157,7 +179,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -173,7 +195,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -189,7 +211,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -217,7 +239,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -268,29 +290,25 @@ def test_lookup_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -299,66 +317,53 @@ def test_lookup_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -384,7 +389,7 @@ def test_lookup_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -414,7 +419,7 @@ def test_lookup_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -433,7 +438,7 @@ def test_lookup_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -472,6 +477,22 @@ def test_resolve_service_from_dict(): test_resolve_service(request_type=dict) +def test_resolve_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = LookupServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resolve_service), "__call__") as call: + client.resolve_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == lookup_service.ResolveServiceRequest() + + @pytest.mark.asyncio async def test_resolve_service_async( transport: str = "grpc_asyncio", request_type=lookup_service.ResolveServiceRequest @@ -716,6 +737,51 @@ def test_lookup_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.LookupServiceGrpcTransport, + transports.LookupServiceGrpcAsyncIOTransport, + ], +) +def test_lookup_service_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_lookup_service_host_no_port(): client = LookupServiceClient( credentials=credentials.AnonymousCredentials(), @@ -737,7 +803,7 @@ def test_lookup_service_host_with_port(): def test_lookup_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.LookupServiceGrpcTransport( @@ -749,7 +815,7 @@ def test_lookup_service_grpc_transport_channel(): def test_lookup_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.LookupServiceGrpcAsyncIOTransport( @@ -760,6 +826,8 @@ def test_lookup_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -772,7 +840,7 @@ def test_lookup_service_transport_channel_mtls_with_client_cert_source(transport "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -810,6 +878,8 @@ def test_lookup_service_transport_channel_mtls_with_client_cert_source(transport assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -825,7 +895,7 @@ def test_lookup_service_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/tests/unit/gapic/servicedirectory_v1/test_registration_service.py b/tests/unit/gapic/servicedirectory_v1/test_registration_service.py index 2d4b9a81..0cd3f3fe 100644 --- a/tests/unit/gapic/servicedirectory_v1/test_registration_service.py +++ b/tests/unit/gapic/servicedirectory_v1/test_registration_service.py @@ -101,7 +101,24 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient] + "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient,] +) +def test_registration_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "servicedirectory.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient,] ) def test_registration_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -111,16 +128,21 @@ def test_registration_service_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "servicedirectory.googleapis.com:443" def test_registration_service_client_get_transport_class(): transport = RegistrationServiceClient.get_transport_class() - assert transport == transports.RegistrationServiceGrpcTransport + available_transports = [ + transports.RegistrationServiceGrpcTransport, + ] + assert transport in available_transports transport = RegistrationServiceClient.get_transport_class("grpc") assert transport == transports.RegistrationServiceGrpcTransport @@ -175,7 +197,7 @@ def test_registration_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +213,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +229,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +257,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +318,25 @@ def test_registration_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +345,53 @@ def test_registration_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +421,7 @@ def test_registration_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +455,7 @@ def test_registration_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +474,7 @@ def test_registration_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -510,6 +515,22 @@ def test_create_namespace_from_dict(): test_create_namespace(request_type=dict) +def test_create_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_namespace), "__call__") as call: + client.create_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateNamespaceRequest() + + @pytest.mark.asyncio async def test_create_namespace_async( transport: str = "grpc_asyncio", @@ -732,6 +753,22 @@ def test_list_namespaces_from_dict(): test_list_namespaces(request_type=dict) +def test_list_namespaces_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_namespaces), "__call__") as call: + client.list_namespaces() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListNamespacesRequest() + + @pytest.mark.asyncio async def test_list_namespaces_async( transport: str = "grpc_asyncio", @@ -1082,6 +1119,22 @@ def test_get_namespace_from_dict(): test_get_namespace(request_type=dict) +def test_get_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_namespace), "__call__") as call: + client.get_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetNamespaceRequest() + + @pytest.mark.asyncio async def test_get_namespace_async( transport: str = "grpc_asyncio", @@ -1276,6 +1329,22 @@ def test_update_namespace_from_dict(): test_update_namespace(request_type=dict) +def test_update_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_namespace), "__call__") as call: + client.update_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateNamespaceRequest() + + @pytest.mark.asyncio async def test_update_namespace_async( transport: str = "grpc_asyncio", @@ -1489,6 +1558,22 @@ def test_delete_namespace_from_dict(): test_delete_namespace(request_type=dict) +def test_delete_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_namespace), "__call__") as call: + client.delete_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteNamespaceRequest() + + @pytest.mark.asyncio async def test_delete_namespace_async( transport: str = "grpc_asyncio", @@ -1679,6 +1764,22 @@ def test_create_service_from_dict(): test_create_service(request_type=dict) +def test_create_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_service), "__call__") as call: + client.create_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateServiceRequest() + + @pytest.mark.asyncio async def test_create_service_async( transport: str = "grpc_asyncio", @@ -1897,6 +1998,22 @@ def test_list_services_from_dict(): test_list_services(request_type=dict) +def test_list_services_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_services), "__call__") as call: + client.list_services() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListServicesRequest() + + @pytest.mark.asyncio async def test_list_services_async( transport: str = "grpc_asyncio", @@ -2231,6 +2348,22 @@ def test_get_service_from_dict(): test_get_service(request_type=dict) +def test_get_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_service), "__call__") as call: + client.get_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetServiceRequest() + + @pytest.mark.asyncio async def test_get_service_async( transport: str = "grpc_asyncio", request_type=registration_service.GetServiceRequest @@ -2424,6 +2557,22 @@ def test_update_service_from_dict(): test_update_service(request_type=dict) +def test_update_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_service), "__call__") as call: + client.update_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateServiceRequest() + + @pytest.mark.asyncio async def test_update_service_async( transport: str = "grpc_asyncio", @@ -2633,6 +2782,22 @@ def test_delete_service_from_dict(): test_delete_service(request_type=dict) +def test_delete_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_service), "__call__") as call: + client.delete_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteServiceRequest() + + @pytest.mark.asyncio async def test_delete_service_async( transport: str = "grpc_asyncio", @@ -2829,6 +2994,22 @@ def test_create_endpoint_from_dict(): test_create_endpoint(request_type=dict) +def test_create_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_endpoint), "__call__") as call: + client.create_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateEndpointRequest() + + @pytest.mark.asyncio async def test_create_endpoint_async( transport: str = "grpc_asyncio", @@ -3055,6 +3236,22 @@ def test_list_endpoints_from_dict(): test_list_endpoints(request_type=dict) +def test_list_endpoints_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_endpoints), "__call__") as call: + client.list_endpoints() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListEndpointsRequest() + + @pytest.mark.asyncio async def test_list_endpoints_async( transport: str = "grpc_asyncio", @@ -3411,6 +3608,22 @@ def test_get_endpoint_from_dict(): test_get_endpoint(request_type=dict) +def test_get_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_endpoint), "__call__") as call: + client.get_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetEndpointRequest() + + @pytest.mark.asyncio async def test_get_endpoint_async( transport: str = "grpc_asyncio", @@ -3615,6 +3828,22 @@ def test_update_endpoint_from_dict(): test_update_endpoint(request_type=dict) +def test_update_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_endpoint), "__call__") as call: + client.update_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateEndpointRequest() + + @pytest.mark.asyncio async def test_update_endpoint_async( transport: str = "grpc_asyncio", @@ -3832,6 +4061,22 @@ def test_delete_endpoint_from_dict(): test_delete_endpoint(request_type=dict) +def test_delete_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_endpoint), "__call__") as call: + client.delete_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteEndpointRequest() + + @pytest.mark.asyncio async def test_delete_endpoint_async( transport: str = "grpc_asyncio", @@ -4024,6 +4269,22 @@ def test_get_iam_policy_from_dict(): test_get_iam_policy(request_type=dict) +def test_get_iam_policy_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call: + client.get_iam_policy() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.GetIamPolicyRequest() + + @pytest.mark.asyncio async def test_get_iam_policy_async( transport: str = "grpc_asyncio", request_type=iam_policy.GetIamPolicyRequest @@ -4168,6 +4429,22 @@ def test_set_iam_policy_from_dict(): test_set_iam_policy(request_type=dict) +def test_set_iam_policy_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call: + client.set_iam_policy() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.SetIamPolicyRequest() + + @pytest.mark.asyncio async def test_set_iam_policy_async( transport: str = "grpc_asyncio", request_type=iam_policy.SetIamPolicyRequest @@ -4314,6 +4591,24 @@ def test_test_iam_permissions_from_dict(): test_test_iam_permissions(request_type=dict) +def test_test_iam_permissions_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_iam_permissions), "__call__" + ) as call: + client.test_iam_permissions() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.TestIamPermissionsRequest() + + @pytest.mark.asyncio async def test_test_iam_permissions_async( transport: str = "grpc_asyncio", request_type=iam_policy.TestIamPermissionsRequest @@ -4605,6 +4900,53 @@ def test_registration_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.RegistrationServiceGrpcTransport, + transports.RegistrationServiceGrpcAsyncIOTransport, + ], +) +def test_registration_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_registration_service_host_no_port(): client = RegistrationServiceClient( credentials=credentials.AnonymousCredentials(), @@ -4626,7 +4968,7 @@ def test_registration_service_host_with_port(): def test_registration_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.RegistrationServiceGrpcTransport( @@ -4638,7 +4980,7 @@ def test_registration_service_grpc_transport_channel(): def test_registration_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.RegistrationServiceGrpcAsyncIOTransport( @@ -4649,6 +4991,8 @@ def test_registration_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -4663,7 +5007,7 @@ def test_registration_service_transport_channel_mtls_with_client_cert_source( "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -4701,6 +5045,8 @@ def test_registration_service_transport_channel_mtls_with_client_cert_source( assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -4716,7 +5062,7 @@ def test_registration_service_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/tests/unit/gapic/servicedirectory_v1beta1/__init__.py b/tests/unit/gapic/servicedirectory_v1beta1/__init__.py index 8b137891..42ffdf2b 100644 --- a/tests/unit/gapic/servicedirectory_v1beta1/__init__.py +++ b/tests/unit/gapic/servicedirectory_v1beta1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# 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. +# diff --git a/tests/unit/gapic/servicedirectory_v1beta1/test_lookup_service.py b/tests/unit/gapic/servicedirectory_v1beta1/test_lookup_service.py index 28985b07..6c0b40d0 100644 --- a/tests/unit/gapic/servicedirectory_v1beta1/test_lookup_service.py +++ b/tests/unit/gapic/servicedirectory_v1beta1/test_lookup_service.py @@ -89,7 +89,24 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [LookupServiceClient, LookupServiceAsyncClient] + "client_class", [LookupServiceClient, LookupServiceAsyncClient,] +) +def test_lookup_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "servicedirectory.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", [LookupServiceClient, LookupServiceAsyncClient,] ) def test_lookup_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -99,16 +116,21 @@ def test_lookup_service_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "servicedirectory.googleapis.com:443" def test_lookup_service_client_get_transport_class(): transport = LookupServiceClient.get_transport_class() - assert transport == transports.LookupServiceGrpcTransport + available_transports = [ + transports.LookupServiceGrpcTransport, + ] + assert transport in available_transports transport = LookupServiceClient.get_transport_class("grpc") assert transport == transports.LookupServiceGrpcTransport @@ -159,7 +181,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -175,7 +197,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +213,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -219,7 +241,7 @@ def test_lookup_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -270,29 +292,25 @@ def test_lookup_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -301,66 +319,53 @@ def test_lookup_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -386,7 +391,7 @@ def test_lookup_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -416,7 +421,7 @@ def test_lookup_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -435,7 +440,7 @@ def test_lookup_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -474,6 +479,22 @@ def test_resolve_service_from_dict(): test_resolve_service(request_type=dict) +def test_resolve_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = LookupServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resolve_service), "__call__") as call: + client.resolve_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == lookup_service.ResolveServiceRequest() + + @pytest.mark.asyncio async def test_resolve_service_async( transport: str = "grpc_asyncio", request_type=lookup_service.ResolveServiceRequest @@ -718,6 +739,51 @@ def test_lookup_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.LookupServiceGrpcTransport, + transports.LookupServiceGrpcAsyncIOTransport, + ], +) +def test_lookup_service_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_lookup_service_host_no_port(): client = LookupServiceClient( credentials=credentials.AnonymousCredentials(), @@ -739,7 +805,7 @@ def test_lookup_service_host_with_port(): def test_lookup_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.LookupServiceGrpcTransport( @@ -751,7 +817,7 @@ def test_lookup_service_grpc_transport_channel(): def test_lookup_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.LookupServiceGrpcAsyncIOTransport( @@ -762,6 +828,8 @@ def test_lookup_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -774,7 +842,7 @@ def test_lookup_service_transport_channel_mtls_with_client_cert_source(transport "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -812,6 +880,8 @@ def test_lookup_service_transport_channel_mtls_with_client_cert_source(transport assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -827,7 +897,7 @@ def test_lookup_service_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/tests/unit/gapic/servicedirectory_v1beta1/test_registration_service.py b/tests/unit/gapic/servicedirectory_v1beta1/test_registration_service.py index 7da36c65..5e4163f8 100644 --- a/tests/unit/gapic/servicedirectory_v1beta1/test_registration_service.py +++ b/tests/unit/gapic/servicedirectory_v1beta1/test_registration_service.py @@ -103,7 +103,24 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient] + "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient,] +) +def test_registration_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "servicedirectory.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", [RegistrationServiceClient, RegistrationServiceAsyncClient,] ) def test_registration_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -113,16 +130,21 @@ def test_registration_service_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "servicedirectory.googleapis.com:443" def test_registration_service_client_get_transport_class(): transport = RegistrationServiceClient.get_transport_class() - assert transport == transports.RegistrationServiceGrpcTransport + available_transports = [ + transports.RegistrationServiceGrpcTransport, + ] + assert transport in available_transports transport = RegistrationServiceClient.get_transport_class("grpc") assert transport == transports.RegistrationServiceGrpcTransport @@ -177,7 +199,7 @@ def test_registration_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -193,7 +215,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -209,7 +231,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -237,7 +259,7 @@ def test_registration_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -298,29 +320,25 @@ def test_registration_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -329,66 +347,53 @@ def test_registration_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -418,7 +423,7 @@ def test_registration_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -452,7 +457,7 @@ def test_registration_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -471,7 +476,7 @@ def test_registration_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -512,6 +517,22 @@ def test_create_namespace_from_dict(): test_create_namespace(request_type=dict) +def test_create_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_namespace), "__call__") as call: + client.create_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateNamespaceRequest() + + @pytest.mark.asyncio async def test_create_namespace_async( transport: str = "grpc_asyncio", @@ -734,6 +755,22 @@ def test_list_namespaces_from_dict(): test_list_namespaces(request_type=dict) +def test_list_namespaces_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_namespaces), "__call__") as call: + client.list_namespaces() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListNamespacesRequest() + + @pytest.mark.asyncio async def test_list_namespaces_async( transport: str = "grpc_asyncio", @@ -1084,6 +1121,22 @@ def test_get_namespace_from_dict(): test_get_namespace(request_type=dict) +def test_get_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_namespace), "__call__") as call: + client.get_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetNamespaceRequest() + + @pytest.mark.asyncio async def test_get_namespace_async( transport: str = "grpc_asyncio", @@ -1278,6 +1331,22 @@ def test_update_namespace_from_dict(): test_update_namespace(request_type=dict) +def test_update_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_namespace), "__call__") as call: + client.update_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateNamespaceRequest() + + @pytest.mark.asyncio async def test_update_namespace_async( transport: str = "grpc_asyncio", @@ -1491,6 +1560,22 @@ def test_delete_namespace_from_dict(): test_delete_namespace(request_type=dict) +def test_delete_namespace_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_namespace), "__call__") as call: + client.delete_namespace() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteNamespaceRequest() + + @pytest.mark.asyncio async def test_delete_namespace_async( transport: str = "grpc_asyncio", @@ -1681,6 +1766,22 @@ def test_create_service_from_dict(): test_create_service(request_type=dict) +def test_create_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_service), "__call__") as call: + client.create_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateServiceRequest() + + @pytest.mark.asyncio async def test_create_service_async( transport: str = "grpc_asyncio", @@ -1899,6 +2000,22 @@ def test_list_services_from_dict(): test_list_services(request_type=dict) +def test_list_services_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_services), "__call__") as call: + client.list_services() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListServicesRequest() + + @pytest.mark.asyncio async def test_list_services_async( transport: str = "grpc_asyncio", @@ -2233,6 +2350,22 @@ def test_get_service_from_dict(): test_get_service(request_type=dict) +def test_get_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_service), "__call__") as call: + client.get_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetServiceRequest() + + @pytest.mark.asyncio async def test_get_service_async( transport: str = "grpc_asyncio", request_type=registration_service.GetServiceRequest @@ -2426,6 +2559,22 @@ def test_update_service_from_dict(): test_update_service(request_type=dict) +def test_update_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_service), "__call__") as call: + client.update_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateServiceRequest() + + @pytest.mark.asyncio async def test_update_service_async( transport: str = "grpc_asyncio", @@ -2635,6 +2784,22 @@ def test_delete_service_from_dict(): test_delete_service(request_type=dict) +def test_delete_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_service), "__call__") as call: + client.delete_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteServiceRequest() + + @pytest.mark.asyncio async def test_delete_service_async( transport: str = "grpc_asyncio", @@ -2831,6 +2996,22 @@ def test_create_endpoint_from_dict(): test_create_endpoint(request_type=dict) +def test_create_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_endpoint), "__call__") as call: + client.create_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.CreateEndpointRequest() + + @pytest.mark.asyncio async def test_create_endpoint_async( transport: str = "grpc_asyncio", @@ -3057,6 +3238,22 @@ def test_list_endpoints_from_dict(): test_list_endpoints(request_type=dict) +def test_list_endpoints_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_endpoints), "__call__") as call: + client.list_endpoints() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.ListEndpointsRequest() + + @pytest.mark.asyncio async def test_list_endpoints_async( transport: str = "grpc_asyncio", @@ -3413,6 +3610,22 @@ def test_get_endpoint_from_dict(): test_get_endpoint(request_type=dict) +def test_get_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_endpoint), "__call__") as call: + client.get_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.GetEndpointRequest() + + @pytest.mark.asyncio async def test_get_endpoint_async( transport: str = "grpc_asyncio", @@ -3617,6 +3830,22 @@ def test_update_endpoint_from_dict(): test_update_endpoint(request_type=dict) +def test_update_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_endpoint), "__call__") as call: + client.update_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.UpdateEndpointRequest() + + @pytest.mark.asyncio async def test_update_endpoint_async( transport: str = "grpc_asyncio", @@ -3834,6 +4063,22 @@ def test_delete_endpoint_from_dict(): test_delete_endpoint(request_type=dict) +def test_delete_endpoint_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_endpoint), "__call__") as call: + client.delete_endpoint() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == registration_service.DeleteEndpointRequest() + + @pytest.mark.asyncio async def test_delete_endpoint_async( transport: str = "grpc_asyncio", @@ -4026,6 +4271,22 @@ def test_get_iam_policy_from_dict(): test_get_iam_policy(request_type=dict) +def test_get_iam_policy_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call: + client.get_iam_policy() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.GetIamPolicyRequest() + + @pytest.mark.asyncio async def test_get_iam_policy_async( transport: str = "grpc_asyncio", request_type=iam_policy.GetIamPolicyRequest @@ -4170,6 +4431,22 @@ def test_set_iam_policy_from_dict(): test_set_iam_policy(request_type=dict) +def test_set_iam_policy_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call: + client.set_iam_policy() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.SetIamPolicyRequest() + + @pytest.mark.asyncio async def test_set_iam_policy_async( transport: str = "grpc_asyncio", request_type=iam_policy.SetIamPolicyRequest @@ -4316,6 +4593,24 @@ def test_test_iam_permissions_from_dict(): test_test_iam_permissions(request_type=dict) +def test_test_iam_permissions_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = RegistrationServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.test_iam_permissions), "__call__" + ) as call: + client.test_iam_permissions() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == iam_policy.TestIamPermissionsRequest() + + @pytest.mark.asyncio async def test_test_iam_permissions_async( transport: str = "grpc_asyncio", request_type=iam_policy.TestIamPermissionsRequest @@ -4607,6 +4902,53 @@ def test_registration_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.RegistrationServiceGrpcTransport, + transports.RegistrationServiceGrpcAsyncIOTransport, + ], +) +def test_registration_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_registration_service_host_no_port(): client = RegistrationServiceClient( credentials=credentials.AnonymousCredentials(), @@ -4628,7 +4970,7 @@ def test_registration_service_host_with_port(): def test_registration_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.RegistrationServiceGrpcTransport( @@ -4640,7 +4982,7 @@ def test_registration_service_grpc_transport_channel(): def test_registration_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.RegistrationServiceGrpcAsyncIOTransport( @@ -4651,6 +4993,8 @@ def test_registration_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -4665,7 +5009,7 @@ def test_registration_service_transport_channel_mtls_with_client_cert_source( "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -4703,6 +5047,8 @@ def test_registration_service_transport_channel_mtls_with_client_cert_source( assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -4718,7 +5064,7 @@ def test_registration_service_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel